Background and Motivation

My M.S. thesis at the University of Chicago developed a novel method to understand and measure value-at-risk, a commonly accepted method to measure downside risk. The metric is understood as follows: a one-day 1% VaR of -10 million dollars for a portfolio means that the portfolio will lose at least 10 million dollars of its value on the 1% worst trading days. A major advantage of VaR is that it distills a distribution of returns into one number. As such, VaR is often used in stress testing by regulatory agencies (Holton 2014).

There have been many popular approaches in the literature to estimate VaR such as modeling the total distribution of returns (Longerstaey and Spencer 1996) and using a semiparametric or a nonparametric historical simulation (Richardson, Boudoukh, and Whitelaw 2005). Engle and Manganelli argue in a 2004 paper (Engle and Manganelli 2004) that while modeling the entire distribution is likely too simplistic, nonparametric methods in the other camp are usually chosen for “empirical justifications rather than on sound statistical theory”. To balance these approaches, they propose a framework called CAViaR that directly forecasts the VaR quantile using a conditional autoregressive quantile specification. This approach builds upon the statistical literature that extends linear quantile models to settings amenable to financial modeling, such as with heteroskedastic and nonstationary error distributions (Portnoy 1991).

My thesis extends the model beyond a univariate setting into a multivariate setting using the diffusion index model, originally developed by Stock and Watson for predicting conditional means (Stock and Watson 2002b, 2002a). My model uses exchange-traded funds (ETFs) as explanatory variables that are combined into principal component vectors at the forecast origin. Combining these principal component vectors with transformations of lagged autoregressive response variables produces similar predictive accuracy during periods of relatively low volatility (when compared to the CAViaR model) along with more insight into the drivers of the changes in the response variable.

Intended Work

As encouraging as the results were from my thesis, two important questions remained unanswered. The first is whether some sort of mixture model would be appropriate, that is, aiming to use the basket of ETFs during good times, and use the CAViaR ARMA specification during bad times. The approach of using ETFs allows a prediction based on forward-looking expectations of fundamental factors. Indeed, ETFs are just baskets of individual stocks or bonds, and those securities are (in theory) based on rational expectations about future resources, market conditions, etc - the microfoundations of what drives our economy. The ARMA specification, while practically and statistically sound, is contradicted by economic theory and practice - the weak form of the efficient market hypothesis states that it is impossible to forecast future values of asset prices using past values. But perhaps this view is incomplete.

To combine these ideas, I will fit a Hidden Markov Model to infer the state of the world - the “rational” one, or the “irrational” one. Given the highly non-normal nature of financial data, I suspect there would be many interesting statistical and computational challenges that would arise with this approach. In addition, it is likely worth exploring alternative ensemble methods to further probe into the seemingly enigmatic nature that pervades financial time series.

When I implement this, the “rational” state of the world will refer to the predictions of one of the multivariate CAViaR models where as the “irrational” state of the world will refer to one of the predictions from the univariate CAViaR models. One way to possibly implement this is to say that if the losses from the multivariate models are lower, then the HMM will lean towards the rational state of the world, otherwise, it will lean towards the other state.

The working directory was changed to /Users/stevenmoen/Documents/GitHub/CAViaR inside a notebook chunk. The working directory will be reset when the chunk is finished running. Use the knitr root.dir option in the setup chunk to change the working directory for notebook chunks.

Hidden Markov Model Work

Below is arguably the most consequential plot from my M.S. thesis. The reasons for this are because it deals with an important VaR Level - 1%, which in the context of trading days means about the worst day out of 100. The biggest takeaway might be the fact that the four lines dashed lines (corresponding to the multivariate CAViaR model) do not perform as well as the last four lines, which refer to the univariate model. This can also be seen in the table of losses printed below.

Notation

Below is the notation used later in this paper. Items 2 - 5 listed below are new multivariate CAViaR models developed in this thesis; models 6 - 9 are from the established univariate CAViaR model developed by Engle and Manganelli.

  1. SPY: SPY ETF
  2. No AR: Multivariate CAViaR Model with no lags
  3. AR: Multivariate CAViaR Model with \(p\) lags
  4. SAV AR: Multivariate CAViaR Model with \(p\) absolute value lags
  5. AS AR: Multivariate CAViaR Model with \(2p\) lags with asymmetric slopes
  6. SAV: Univariate CAViaR Model with symmetric absolute framework
  7. Asym. Slope: Univariate CAViaR Model with asymmetric slope framework
  8. Ind. GARCH: Univariate CAViaR Model with indirect GARCH framework
  9. Adaptive: Univariate CAViaR Model with adaptive slope framework

Losses Over the Last 250 Trading Days in 2008 for the Multivariate CAViaR Models
No AR AR SAV AR AS AR
Losses by Model 0.736 0.737 1.733 0.863
Losses Over the Last 250 Trading Days in 2008 for the Univariate CAViaR Models
SAV Asym. Slope Ind. GARCH Adaptive
Losses by Model 0.208 0.213 0.219 0.355

Based on the losses for each model during the last 250 trading days in 2008, it looks like the best options are the multivariate CAViaR model without AR terms for the multivariate model class and the symmetric absolute value model for the univariate model class. The full model specifications can be found in the appendix.

Coincidentally, these are among the simplest models available among the models plotted above. A natural criticism of this approach is that the losses are lower for the CAViaR specifications without lagged predictors. This is a fair point, however, the period of 2008 is a period of extreme crisis, and a simpler, ARMA-style model might seem to work better other things equal. Future work can extend this work to other periods. Since these are the best two options during this period of interest, the next step is to find reasonable parametric distributions to model their values.

Finding Distributions of the Forecasts

To fit the Hidden Markov Model, it is necessary to find distributions that appropriately fit the two models above. While the distribution of predictions from the multivariate model is fairly well-approximated by a normal distribution, the distribution of predictions from the univariate model was highly left-skewed, which makes fitting a distribution difficult.

The first step was to try transformations of the aforementioned predictions from the univariate model, namely \(\sqrt{\max(x+1) -x}\), \(\log_{10} (\max(x+1) -x)\), and \(1/(\max(x+1) -x)\) following the suggestions found here (Kassambara 2018). While these did (in some cases) eliminate the left-skew, it often created a more pronounced right-skew! Thus, I attempted to model the data without transformation.

There are many candidate distributions that could be used to model the empirical distribution of values from the univariate CAViaR model, but the three that stood out are:

  1. The Skew Normal Distribution (parameterized by location, scale, and shape parameters)
  2. The Gumbel Distribution (parameterized by location and scale parameters)
  3. The Generalized Extreme Value Distribution (parameterized by location, scale, and shape parameters)
NA/NaN function evaluationNA/NaN function evaluationNA/NaN function evaluationNA/NaN function evaluationNA/NaN function evaluationNA/NaN function evaluationNA/NaN function evaluationNA/NaN function evaluationNA/NaN function evaluationNA/NaN function evaluation

To fit the above histograms,the optimal parameters were fit using maximum likelihood. Note that while there were convergence issues used in fitting the skew-normal distribution, there were not issues with fitting the Gumbel or the GEV distributions.

Optimal Parameters for the Normal Distribution
Mean Standard Deviation
Optimal Parameters -0.03 0.01
Note:
The Mean Was Estimated Using the Sample Mean, SD was Estimated Using Sample Std. Dev.
Optimal Parameters for the Candidate Distributions
Location Scale Shape
Skew Normal -0.059 0.029 0.002
Gumbel -0.072 0.044 NA
GEV -0.045 0.028 -1.174
Note:
Estimated Using Maximum Likelihood

To evaluate the model fit more rigorously, I compared the Kullback-Leibler divergence for each theoretical distribution.

argument ‘freq’ is not made use of
Comparing K-L Divergences By Model Fits
Skew-Normal Gumbel GEV
Mean Sum K-L Divergence 22.52 25.4 17.71

Based on the K-L Divergence, it would seem to make sense to use the generalized extreme value distribution, however, the problem with doing this is the fact that this distribution doesn’t have support over the entire real line. Moreover, the Skew-Normal distribution did not work well when fitting the Hidden Markov Model. Therefore, the Gumbel is used in fitting the HMM below.

HMM Background and Results

The motivating idea behind a Hidden Markov Model is that there are 2 unknown latent states \(k\) that generate the data that is seen. (The reference for this information is given here (Stephens 2018)). The algorithm implemented here computes forwards probabilities, \(\alpha_{tk} = \mathbb{P}(X_1, ... , X_t; Z_t = k)\). To start, one simply multiplies an equally-weighted prior \(\pi_k = 0.5\) by the likelihood of the data given each state, given by \(\mathbb{P}(X_1 | Z_1 = k\)).

The likelihood function for the “rational” state (represented by the multivariate CAViaR model) is represented by a normal distribution whereas the likelihood function for the “irrational” state (represented by the univariate CAViaR model) is represented by the Gumbel distribution. Both use the parameters estimated above.

Now, once the \(\alpha_1\) value is calculate, \(\alpha_2\) is calculated as follows, with a similar process for an arbitrary value \(\alpha_t\).

\[ \alpha_2 = (\alpha_1 P)_k \mathbb{P}(X_2 | Z_2 = k) \]

The \(P\) symbol corresponds to a symmetric 2x2 transition matrix where the first row is \((0.9, 0.1)\) and the second row is \((0.1, 0.9)\).

To compute the backwards probabilities, we compute the following \(\beta_{tk} = \mathbb{P}(X_{t+1}, ... , X_T; Z_t = k)\), and then the posterior distribution for each state \(Z_t\) is given by the following:

\[ \mathbb{P}(Z_t = k| X_1, ..., X_T) = \alpha_{tk} \beta_{tk} / \sum_{k}\alpha_{tk} \beta_{tk} \]

[1] -0.02580552 -0.05929181 -0.07157664 -0.04463765
[1] -0.02580552

FUNCTIONS

[1] 1 2 6
[1] "The best multivariate CAViaR model for the time period from 2008-01-04 to 2008-12-30 is No AR and the best univariate CAViaR model for the time period is SAV"
NA/NaN function evaluationNA/NaN function evaluationNA/NaN function evaluationNA/NaN function evaluationNA/NaN function evaluationNA/NaN function evaluationNA/NaN function evaluation

Optimal Parameters for the Candidate Distributions
Location Scale Shape
Skew Normal -0.059 0.029 0.002
Gumbel -0.072 0.044 NA
Note:
Estimated Using Maximum Likelihood
Comparing K-L Divergences By Model Fits
Skew-Normal Gumbel
Mean Sum K-L Divergence 22.52 25.4

NA/NaN function evaluationNA/NaN function evaluationNA/NaN function evaluation

Optimal Parameters for the Candidate Distributions
Location Scale Shape
Normal -0.026 0.006 NA
Skew Normal -0.026 0.006 1
Note:
Estimated Using Maximum Likelihood
Comparing K-L Divergences By Model Fits
Normal Skew-Normal
Mean Sum K-L Divergence 38.51 39.92

                  No AR
2008-01-04 -0.026444959
2008-01-07 -0.020918853
2008-01-08 -0.027358383
2008-01-09 -0.023037345
2008-01-10 -0.029578406
2008-01-11 -0.027805198
2008-01-14 -0.022418699
2008-01-15 -0.028390598
2008-01-16 -0.020466743
2008-01-17 -0.023153214
2008-01-18 -0.019742037
2008-01-22 -0.025604119
2008-01-23 -0.021146953
2008-01-24 -0.029236450
2008-01-25 -0.030146841
2008-01-28 -0.022484695
2008-01-29 -0.029565098
2008-01-30 -0.028132052
2008-01-31 -0.025308613
2008-02-01 -0.029568576
2008-02-04 -0.029801324
2008-02-05 -0.024775834
2008-02-06 -0.017892361
2008-02-07 -0.025454797
2008-02-08 -0.027897476
2008-02-11 -0.024721783
2008-02-12 -0.027961724
2008-02-13 -0.029262840
2008-02-14 -0.029147166
2008-02-15 -0.023925289
2008-02-19 -0.026778118
2008-02-20 -0.028232759
2008-02-21 -0.026148107
2008-02-22 -0.023615912
2008-02-25 -0.028752457
2008-02-26 -0.029811229
2008-02-27 -0.028070952
2008-02-28 -0.025744198
2008-02-29 -0.023602175
2008-03-03 -0.019287618
2008-03-04 -0.027263590
2008-03-05 -0.025250672
2008-03-06 -0.028314641
2008-03-07 -0.022177812
2008-03-10 -0.023182481
2008-03-11 -0.022729370
2008-03-12 -0.034702322
2008-03-13 -0.024116227
2008-03-14 -0.027954058
2008-03-17 -0.021158975
2008-03-18 -0.023265262
2008-03-19 -0.034754001
2008-03-20 -0.019169495
2008-03-24 -0.029489402
2008-03-25 -0.032241352
2008-03-26 -0.027521124
2008-03-27 -0.024744013
2008-03-28 -0.025729120
2008-03-31 -0.024360891
2008-04-01 -0.026948832
2008-04-02 -0.033703823
2008-04-03 -0.026854724
2008-04-04 -0.026883362
2008-04-07 -0.026368007
2008-04-08 -0.027083168
2008-04-09 -0.025691962
2008-04-10 -0.023673101
2008-04-11 -0.027476880
2008-04-14 -0.021568622
2008-04-15 -0.026300678
2008-04-16 -0.027683347
2008-04-17 -0.032672141
2008-04-18 -0.025617324
2008-04-21 -0.029403109
2008-04-22 -0.026617214
2008-04-23 -0.024029767
2008-04-24 -0.026837334
2008-04-25 -0.027721453
2008-04-28 -0.027792210
2008-04-29 -0.026405471
2008-04-30 -0.024352679
2008-05-01 -0.025132710
2008-05-02 -0.030034470
2008-05-05 -0.027569707
2008-05-06 -0.026007771
2008-05-07 -0.028080086
2008-05-08 -0.022044541
2008-05-09 -0.027064267
2008-05-12 -0.025116123
2008-05-13 -0.029225697
2008-05-14 -0.026810104
2008-05-15 -0.027244536
2008-05-16 -0.028384815
2008-05-19 -0.027377138
2008-05-20 -0.026827534
2008-05-21 -0.024141136
2008-05-22 -0.023041642
2008-05-23 -0.028034126
2008-05-27 -0.023274637
2008-05-28 -0.027569833
2008-05-29 -0.027752662
2008-05-30 -0.027749671
2008-06-02 -0.026567152
2008-06-03 -0.023526519
2008-06-04 -0.025274828
2008-06-05 -0.026226035
2008-06-06 -0.030906098
2008-06-09 -0.018648981
2008-06-10 -0.027179468
2008-06-11 -0.024984332
2008-06-12 -0.022598243
2008-06-13 -0.027495767
2008-06-16 -0.029241178
2008-06-17 -0.026258119
2008-06-18 -0.025604857
2008-06-19 -0.023542138
2008-06-20 -0.027405997
2008-06-23 -0.021399427
2008-06-24 -0.026301878
2008-06-25 -0.025246676
2008-06-26 -0.028475390
2008-06-27 -0.019781488
2008-06-30 -0.024749664
2008-07-01 -0.027533488
2008-07-02 -0.025595751
2008-07-03 -0.022590912
2008-07-07 -0.026553949
2008-07-08 -0.025137187
2008-07-09 -0.029515894
2008-07-10 -0.022276711
2008-07-11 -0.027823032
2008-07-14 -0.023877019
2008-07-15 -0.024945139
2008-07-16 -0.023910710
2008-07-17 -0.031348855
2008-07-18 -0.028617128
2008-07-21 -0.027383727
2008-07-22 -0.026385886
2008-07-23 -0.028495557
2008-07-24 -0.026833918
2008-07-25 -0.021383486
2008-07-28 -0.027096031
2008-07-29 -0.022496218
2008-07-30 -0.031067889
2008-07-31 -0.028788933
2008-08-01 -0.023291505
2008-08-04 -0.023903695
2008-08-05 -0.025190192
2008-08-06 -0.032129294
2008-08-07 -0.027742140
2008-08-08 -0.021209114
2008-08-11 -0.030513767
2008-08-12 -0.027865702
2008-08-13 -0.024105176
2008-08-14 -0.025542910
2008-08-15 -0.026245996
2008-08-18 -0.026613591
2008-08-19 -0.023553508
2008-08-20 -0.024330879
2008-08-21 -0.026795849
2008-08-22 -0.027247434
2008-08-25 -0.028949829
2008-08-26 -0.021701700
2008-08-27 -0.026963793
2008-08-28 -0.028186676
2008-08-29 -0.029165714
2008-09-02 -0.024082820
2008-09-03 -0.024469891
2008-09-04 -0.024935206
2008-09-05 -0.018616531
2008-09-08 -0.026300351
2008-09-09 -0.030153767
2008-09-10 -0.019440593
2008-09-11 -0.027513255
2008-09-12 -0.028796725
2008-09-15 -0.029062906
2008-09-16 -0.015215866
2008-09-17 -0.029575004
2008-09-18 -0.016262773
2008-09-19 -0.034642034
2008-09-22 -0.037227119
2008-09-23 -0.018079585
2008-09-24 -0.022774355
2008-09-25 -0.025620493
2008-09-26 -0.030915628
2008-09-29 -0.026344767
2008-09-30 -0.007440322
2008-10-01 -0.034305103
2008-10-02 -0.025081389
2008-10-03 -0.016489088
2008-10-06 -0.022293863
2008-10-07 -0.014060898
2008-10-08 -0.015185766
2008-10-09 -0.023492862
2008-10-10 -0.010000901
2008-10-13 -0.023535782
2008-10-14 -0.051274373
2008-10-15 -0.026052429
2008-10-16 -0.003190493
2008-10-17 -0.034481766
2008-10-20 -0.025914559
2008-10-21 -0.036948434
2008-10-22 -0.018133787
2008-10-23 -0.011176478
2008-10-24 -0.027500024
2008-10-27 -0.016759548
2008-10-28 -0.017520132
2008-10-29 -0.050127961
2008-10-30 -0.027291377
2008-10-31 -0.034134096
2008-11-03 -0.029028249
2008-11-04 -0.025834556
2008-11-05 -0.035973487
2008-11-06 -0.014296162
2008-11-07 -0.013307908
2008-11-10 -0.034247339
2008-11-11 -0.023670742
2008-11-12 -0.019946894
2008-11-13 -0.014484600
2008-11-14 -0.043607796
2008-11-17 -0.015243901
2008-11-18 -0.020421108
2008-11-19 -0.025625367
2008-11-20 -0.011892599
2008-11-21 -0.011049316
2008-11-24 -0.039323062
2008-11-25 -0.040904645
2008-11-26 -0.028439678
2008-11-28 -0.032294970
2008-12-01 -0.027932535
2008-12-02 -0.004598641
2008-12-03 -0.035751142
2008-12-04 -0.030666196
2008-12-05 -0.019087462
2008-12-08 -0.034429597
2008-12-09 -0.034670831
2008-12-10 -0.021499779
2008-12-11 -0.030280693
2008-12-12 -0.020760966
2008-12-15 -0.027463873
2008-12-16 -0.024907562
2008-12-17 -0.037581081
2008-12-18 -0.024360402
2008-12-19 -0.019931054
2008-12-22 -0.026353159
2008-12-23 -0.022467319
2008-12-24 -0.024390683
2008-12-26 -0.027612680
2008-12-29 -0.027348239
2008-12-30 -0.025267786

MASTER FUNCTION

RESULTS FROM MASTER FUNCTION

2008

1% TP

[1] "The best multivariate CAViaR model for the time period from 2008-01-04 to 2008-12-30 is No AR and the best univariate CAViaR model for the time period is SAV"
NA/NaN function evaluationNA/NaN function evaluationNA/NaN function evaluationNA/NaN function evaluationNA/NaN function evaluationNA/NaN function evaluationNA/NaN function evaluation

Optimal Parameters for the Candidate Distributions
Location Scale Shape
Skew Normal -0.059 0.029 0.002
Gumbel -0.072 0.044 NA
Note:
Estimated Using Maximum Likelihood
Comparing K-L Divergences By Model Fits
Skew-Normal Gumbel
Mean Sum K-L Divergence 22.52 25.4

Optimal Parameters for the Candidate Distributions
Location Scale Shape
Normal -0.026 0.006 NA
Skew Normal -0.026 0.006 1
Note:
Estimated Using Maximum Likelihood
Comparing K-L Divergences By Model Fits
Normal Skew-Normal
Mean Sum K-L Divergence 38.51 39.92

[1] "The best multivariate CAViaR model for the time period from 2008-01-04 to 2008-12-30 is No AR and the best univariate CAViaR model for the time period is Ind. GARCH"
NA/NaN function evaluationNA/NaN function evaluationNA/NaN function evaluationNA/NaN function evaluationNA/NaN function evaluation

Optimal Parameters for the Candidate Distributions
Location Scale Shape
Skew Normal -0.044 0.022 0.002
Gumbel -0.054 0.033 NA
Note:
Estimated Using Maximum Likelihood
Comparing K-L Divergences By Model Fits
Skew-Normal Gumbel
Mean Sum K-L Divergence 22.52 23.91

NA/NaN function evaluationNA/NaN function evaluationNA/NaN function evaluation

Optimal Parameters for the Candidate Distributions
Location Scale Shape
Normal -0.017 0.006 NA
Skew Normal -0.017 0.006 1
Note:
Estimated Using Maximum Likelihood
Comparing K-L Divergences By Model Fits
Normal Skew-Normal
Mean Sum K-L Divergence 51.92 39.92

[1] "The best multivariate CAViaR model for the time period from 2008-01-04 to 2008-12-30 is No AR and the best univariate CAViaR model for the time period is Asym. Slope"
NA/NaN function evaluationNA/NaN function evaluationNA/NaN function evaluationNA/NaN function evaluationNA/NaN function evaluationNA/NaN function evaluationNA/NaN function evaluationNA/NaN function evaluationNA/NaN function evaluationNA/NaN function evaluation

Optimal Parameters for the Candidate Distributions
Location Scale Shape
Skew Normal -0.030 0.016 0.003
Gumbel -0.037 0.025 NA
Note:
Estimated Using Maximum Likelihood
Comparing K-L Divergences By Model Fits
Skew-Normal Gumbel
Mean Sum K-L Divergence 22.52 20.43

NA/NaN function evaluationNA/NaN function evaluationNA/NaN function evaluation

Optimal Parameters for the Candidate Distributions
Location Scale Shape
Normal -0.011 0.001 NA
Skew Normal -0.011 0.001 1
Note:
Estimated Using Maximum Likelihood
Comparing K-L Divergences By Model Fits
Normal Skew-Normal
Mean Sum K-L Divergence 114.08 39.92

5% TP

[1] "The best multivariate CAViaR model for the time period from 2008-01-04 to 2008-12-30 is No AR and the best univariate CAViaR model for the time period is SAV"
NA/NaN function evaluationNA/NaN function evaluationNA/NaN function evaluationNA/NaN function evaluationNA/NaN function evaluationNA/NaN function evaluationNA/NaN function evaluation

Optimal Parameters for the Candidate Distributions
Location Scale Shape
Skew Normal -0.059 0.029 0.002
Gumbel -0.072 0.044 NA
Note:
Estimated Using Maximum Likelihood
Comparing K-L Divergences By Model Fits
Skew-Normal Gumbel
Mean Sum K-L Divergence 22.52 25.4

Optimal Parameters for the Candidate Distributions
Location Scale Shape
Normal -0.026 0.006 NA
Skew Normal -0.026 0.006 1
Note:
Estimated Using Maximum Likelihood
Comparing K-L Divergences By Model Fits
Normal Skew-Normal
Mean Sum K-L Divergence 38.51 39.92

[1] "The best multivariate CAViaR model for the time period from 2008-01-04 to 2008-12-30 is No AR and the best univariate CAViaR model for the time period is Ind. GARCH"
NA/NaN function evaluationNA/NaN function evaluationNA/NaN function evaluationNA/NaN function evaluationNA/NaN function evaluation

Optimal Parameters for the Candidate Distributions
Location Scale Shape
Skew Normal -0.044 0.022 0.002
Gumbel -0.054 0.033 NA
Note:
Estimated Using Maximum Likelihood
Comparing K-L Divergences By Model Fits
Skew-Normal Gumbel
Mean Sum K-L Divergence 22.52 23.91

NA/NaN function evaluationNA/NaN function evaluationNA/NaN function evaluation

Optimal Parameters for the Candidate Distributions
Location Scale Shape
Normal -0.017 0.006 NA
Skew Normal -0.017 0.006 1
Note:
Estimated Using Maximum Likelihood
Comparing K-L Divergences By Model Fits
Normal Skew-Normal
Mean Sum K-L Divergence 51.92 39.92

[1] "The best multivariate CAViaR model for the time period from 2008-01-04 to 2008-12-30 is No AR and the best univariate CAViaR model for the time period is Asym. Slope"
NA/NaN function evaluationNA/NaN function evaluationNA/NaN function evaluationNA/NaN function evaluationNA/NaN function evaluationNA/NaN function evaluationNA/NaN function evaluationNA/NaN function evaluationNA/NaN function evaluationNA/NaN function evaluation

Optimal Parameters for the Candidate Distributions
Location Scale Shape
Skew Normal -0.030 0.016 0.003
Gumbel -0.037 0.025 NA
Note:
Estimated Using Maximum Likelihood
Comparing K-L Divergences By Model Fits
Skew-Normal Gumbel
Mean Sum K-L Divergence 22.52 20.43

NA/NaN function evaluationNA/NaN function evaluationNA/NaN function evaluation

Optimal Parameters for the Candidate Distributions
Location Scale Shape
Normal -0.011 0.001 NA
Skew Normal -0.011 0.001 1
Note:
Estimated Using Maximum Likelihood
Comparing K-L Divergences By Model Fits
Normal Skew-Normal
Mean Sum K-L Divergence 114.08 39.92

10% TP

[1] "The best multivariate CAViaR model for the time period from 2008-01-04 to 2008-12-30 is No AR and the best univariate CAViaR model for the time period is SAV"
NA/NaN function evaluationNA/NaN function evaluationNA/NaN function evaluationNA/NaN function evaluationNA/NaN function evaluationNA/NaN function evaluationNA/NaN function evaluation

Optimal Parameters for the Candidate Distributions
Location Scale Shape
Skew Normal -0.059 0.029 0.002
Gumbel -0.072 0.044 NA
Note:
Estimated Using Maximum Likelihood
Comparing K-L Divergences By Model Fits
Skew-Normal Gumbel
Mean Sum K-L Divergence 22.52 25.4

Optimal Parameters for the Candidate Distributions
Location Scale Shape
Normal -0.026 0.006 NA
Skew Normal -0.026 0.006 1
Note:
Estimated Using Maximum Likelihood
Comparing K-L Divergences By Model Fits
Normal Skew-Normal
Mean Sum K-L Divergence 38.51 39.92

[1] "The best multivariate CAViaR model for the time period from 2008-01-04 to 2008-12-30 is No AR and the best univariate CAViaR model for the time period is Ind. GARCH"
NA/NaN function evaluationNA/NaN function evaluationNA/NaN function evaluationNA/NaN function evaluationNA/NaN function evaluation

Optimal Parameters for the Candidate Distributions
Location Scale Shape
Skew Normal -0.044 0.022 0.002
Gumbel -0.054 0.033 NA
Note:
Estimated Using Maximum Likelihood
Comparing K-L Divergences By Model Fits
Skew-Normal Gumbel
Mean Sum K-L Divergence 22.52 23.91

NA/NaN function evaluationNA/NaN function evaluationNA/NaN function evaluation

Optimal Parameters for the Candidate Distributions
Location Scale Shape
Normal -0.017 0.006 NA
Skew Normal -0.017 0.006 1
Note:
Estimated Using Maximum Likelihood
Comparing K-L Divergences By Model Fits
Normal Skew-Normal
Mean Sum K-L Divergence 51.92 39.92

[1] "The best multivariate CAViaR model for the time period from 2008-01-04 to 2008-12-30 is No AR and the best univariate CAViaR model for the time period is Asym. Slope"
NA/NaN function evaluationNA/NaN function evaluationNA/NaN function evaluationNA/NaN function evaluationNA/NaN function evaluationNA/NaN function evaluationNA/NaN function evaluationNA/NaN function evaluationNA/NaN function evaluationNA/NaN function evaluation

Optimal Parameters for the Candidate Distributions
Location Scale Shape
Skew Normal -0.030 0.016 0.003
Gumbel -0.037 0.025 NA
Note:
Estimated Using Maximum Likelihood
Comparing K-L Divergences By Model Fits
Skew-Normal Gumbel
Mean Sum K-L Divergence 22.52 20.43

NA/NaN function evaluationNA/NaN function evaluationNA/NaN function evaluation

Optimal Parameters for the Candidate Distributions
Location Scale Shape
Normal -0.011 0.001 NA
Skew Normal -0.011 0.001 1
Note:
Estimated Using Maximum Likelihood
Comparing K-L Divergences By Model Fits
Normal Skew-Normal
Mean Sum K-L Divergence 114.08 39.92

20% TP

[1] "The best multivariate CAViaR model for the time period from 2008-01-04 to 2008-12-30 is No AR and the best univariate CAViaR model for the time period is SAV"
NA/NaN function evaluationNA/NaN function evaluationNA/NaN function evaluationNA/NaN function evaluationNA/NaN function evaluationNA/NaN function evaluationNA/NaN function evaluation

Optimal Parameters for the Candidate Distributions
Location Scale Shape
Skew Normal -0.059 0.029 0.002
Gumbel -0.072 0.044 NA
Note:
Estimated Using Maximum Likelihood
Comparing K-L Divergences By Model Fits
Skew-Normal Gumbel
Mean Sum K-L Divergence 22.52 25.4

Optimal Parameters for the Candidate Distributions
Location Scale Shape
Normal -0.026 0.006 NA
Skew Normal -0.026 0.006 1
Note:
Estimated Using Maximum Likelihood
Comparing K-L Divergences By Model Fits
Normal Skew-Normal
Mean Sum K-L Divergence 38.51 39.92

[1] "The best multivariate CAViaR model for the time period from 2008-01-04 to 2008-12-30 is No AR and the best univariate CAViaR model for the time period is Ind. GARCH"
NA/NaN function evaluationNA/NaN function evaluationNA/NaN function evaluationNA/NaN function evaluationNA/NaN function evaluation

Optimal Parameters for the Candidate Distributions
Location Scale Shape
Skew Normal -0.044 0.022 0.002
Gumbel -0.054 0.033 NA
Note:
Estimated Using Maximum Likelihood
Comparing K-L Divergences By Model Fits
Skew-Normal Gumbel
Mean Sum K-L Divergence 22.52 23.91

NA/NaN function evaluationNA/NaN function evaluationNA/NaN function evaluation

Optimal Parameters for the Candidate Distributions
Location Scale Shape
Normal -0.017 0.006 NA
Skew Normal -0.017 0.006 1
Note:
Estimated Using Maximum Likelihood
Comparing K-L Divergences By Model Fits
Normal Skew-Normal
Mean Sum K-L Divergence 51.92 39.92

[1] "The best multivariate CAViaR model for the time period from 2008-01-04 to 2008-12-30 is No AR and the best univariate CAViaR model for the time period is Asym. Slope"
NA/NaN function evaluationNA/NaN function evaluationNA/NaN function evaluationNA/NaN function evaluationNA/NaN function evaluationNA/NaN function evaluationNA/NaN function evaluationNA/NaN function evaluationNA/NaN function evaluationNA/NaN function evaluation

Optimal Parameters for the Candidate Distributions
Location Scale Shape
Skew Normal -0.030 0.016 0.003
Gumbel -0.037 0.025 NA
Note:
Estimated Using Maximum Likelihood
Comparing K-L Divergences By Model Fits
Skew-Normal Gumbel
Mean Sum K-L Divergence 22.52 20.43

NA/NaN function evaluationNA/NaN function evaluationNA/NaN function evaluation

Optimal Parameters for the Candidate Distributions
Location Scale Shape
Normal -0.011 0.001 NA
Skew Normal -0.011 0.001 1
Note:
Estimated Using Maximum Likelihood
Comparing K-L Divergences By Model Fits
Normal Skew-Normal
Mean Sum K-L Divergence 114.08 39.92

33% TP

[1] "The best multivariate CAViaR model for the time period from 2008-01-04 to 2008-12-30 is No AR and the best univariate CAViaR model for the time period is SAV"
NA/NaN function evaluationNA/NaN function evaluationNA/NaN function evaluationNA/NaN function evaluationNA/NaN function evaluationNA/NaN function evaluationNA/NaN function evaluation

Optimal Parameters for the Candidate Distributions
Location Scale Shape
Skew Normal -0.059 0.029 0.002
Gumbel -0.072 0.044 NA
Note:
Estimated Using Maximum Likelihood
Comparing K-L Divergences By Model Fits
Skew-Normal Gumbel
Mean Sum K-L Divergence 22.52 25.4

Optimal Parameters for the Candidate Distributions
Location Scale Shape
Normal -0.026 0.006 NA
Skew Normal -0.026 0.006 1
Note:
Estimated Using Maximum Likelihood
Comparing K-L Divergences By Model Fits
Normal Skew-Normal
Mean Sum K-L Divergence 38.51 39.92

[1] "The best multivariate CAViaR model for the time period from 2008-01-04 to 2008-12-30 is No AR and the best univariate CAViaR model for the time period is Ind. GARCH"
NA/NaN function evaluationNA/NaN function evaluationNA/NaN function evaluationNA/NaN function evaluationNA/NaN function evaluation

Optimal Parameters for the Candidate Distributions
Location Scale Shape
Skew Normal -0.044 0.022 0.002
Gumbel -0.054 0.033 NA
Note:
Estimated Using Maximum Likelihood
Comparing K-L Divergences By Model Fits
Skew-Normal Gumbel
Mean Sum K-L Divergence 22.52 23.91

NA/NaN function evaluationNA/NaN function evaluationNA/NaN function evaluation

Optimal Parameters for the Candidate Distributions
Location Scale Shape
Normal -0.017 0.006 NA
Skew Normal -0.017 0.006 1
Note:
Estimated Using Maximum Likelihood
Comparing K-L Divergences By Model Fits
Normal Skew-Normal
Mean Sum K-L Divergence 51.92 39.92

[1] "The best multivariate CAViaR model for the time period from 2008-01-04 to 2008-12-30 is No AR and the best univariate CAViaR model for the time period is Asym. Slope"
NA/NaN function evaluationNA/NaN function evaluationNA/NaN function evaluationNA/NaN function evaluationNA/NaN function evaluationNA/NaN function evaluationNA/NaN function evaluationNA/NaN function evaluationNA/NaN function evaluationNA/NaN function evaluation

Optimal Parameters for the Candidate Distributions
Location Scale Shape
Skew Normal -0.030 0.016 0.003
Gumbel -0.037 0.025 NA
Note:
Estimated Using Maximum Likelihood
Comparing K-L Divergences By Model Fits
Skew-Normal Gumbel
Mean Sum K-L Divergence 22.52 20.43

NA/NaN function evaluationNA/NaN function evaluationNA/NaN function evaluation

Optimal Parameters for the Candidate Distributions
Location Scale Shape
Normal -0.011 0.001 NA
Skew Normal -0.011 0.001 1
Note:
Estimated Using Maximum Likelihood
Comparing K-L Divergences By Model Fits
Normal Skew-Normal
Mean Sum K-L Divergence 114.08 39.92

2010

[1] "The best multivariate CAViaR model for the time period from 2010-01-05 to 2010-12-30 is SAV AR and the best univariate CAViaR model for the time period is SAV"
NA/NaN function evaluationNA/NaN function evaluationNA/NaN function evaluationNA/NaN function evaluationNA/NaN function evaluation

Optimal Parameters for the Candidate Distributions
Location Scale Shape
Skew Normal -0.029 0.008 0.219
Gumbel -0.033 0.008 NA
Note:
Estimated Using Maximum Likelihood
Comparing K-L Divergences By Model Fits
Skew-Normal Gumbel
Mean Sum K-L Divergence 22.52 0.02

Optimal Parameters for the Candidate Distributions
Location Scale Shape
Normal -0.045 0.005 NA
Skew Normal -0.045 0.005 1
Note:
Estimated Using Maximum Likelihood
Comparing K-L Divergences By Model Fits
Normal Skew-Normal
Mean Sum K-L Divergence 66.47 39.92

2014

2016

To fit the above histograms,the optimal parameters were fit using maximum likelihood. Note that while there were convergence issues used in fitting the skew-normal distribution, there were not issues with fitting the Gumbel or the GEV distributions.

To evaluate the model fit more rigorously, I compared the Kullback-Leibler divergence for each theoretical distribution.

Based on the losses for each model during the last 250 trading days in 2008, it looks like the best options are the multivariate CAViaR model without AR terms for the multivariate model class and the symmetric absolute value model for the univariate model class. The full model specifications can be found in the appendix.

Coincidentally, these are among the simplest models available among the models plotted above. A natural criticism of this approach is that the losses are lower for the CAViaR specifications without lagged predictors. This is a fair point, however, the period of 2008 is a period of extreme crisis, and a simpler, ARMA-style model might seem to work better other things equal. Future work can extend this work to other periods. Since these are the best two options during this period of interest, the next step is to find reasonable parametric distributions to model their values.

Finding Distributions of the Forecasts

To fit the Hidden Markov Model, it is necessary to find distributions that appropriately fit the two models above. While the distribution of predictions from the multivariate model is fairly well-approximated by a normal distribution, the distribution of predictions from the univariate model was highly left-skewed, which makes fitting a distribution difficult.

The first step was to try transformations of the aforementioned predictions from the univariate model, namely \(\sqrt{\max(x+1) -x}\), \(\log_{10} (\max(x+1) -x)\), and \(1/(\max(x+1) -x)\) following the suggestions found here (Kassambara 2018). While these did (in some cases) eliminate the left-skew, it often created a more pronounced right-skew! Thus, I attempted to model the data without transformation.

There are many candidate distributions that could be used to model the empirical distribution of values from the univariate CAViaR model, but the three that stood out are:

  1. The Skew Normal Distribution (parameterized by location, scale, and shape parameters)
  2. The Gumbel Distribution (parameterized by location and scale parameters)
  3. The Generalized Extreme Value Distribution (parameterized by location, scale, and shape parameters)

To fit the above histograms,the optimal parameters were fit using maximum likelihood. Note that while there were convergence issues used in fitting the skew-normal distribution, there were not issues with fitting the Gumbel or the GEV distributions.

To evaluate the model fit more rigorously, I compared the Kullback-Leibler divergence for each theoretical distribution.

Based on the K-L Divergence, it would seem to make sense to use the generalized extreme value distribution, however, the problem with doing this is the fact that this distribution doesn’t have support over the entire real line. Moreover, the Skew-Normal distribution did not work well when fitting the Hidden Markov Model. Therefore, the Gumbel is used in fitting the HMM below.

HMM Background and Results

The motivating idea behind a Hidden Markov Model is that there are 2 unknown latent states \(k\) that generate the data that is seen. (The reference for this information is given here (Stephens 2018)). The algorithm implemented here computes forwards probabilities, \(\alpha_{tk} = \mathbb{P}(X_1, ... , X_t; Z_t = k)\). To start, one simply multiplies an equally-weighted prior \(\pi_k = 0.5\) by the likelihood of the data given each state, given by \(\mathbb{P}(X_1 | Z_1 = k\)).

The likelihood function for the “rational” state (represented by the multivariate CAViaR model) is represented by a normal distribution whereas the likelihood function for the “irrational” state (represented by the univariate CAViaR model) is represented by the Gumbel distribution. Both use the parameters estimated above.

Now, once the \(\alpha_1\) value is calculate, \(\alpha_2\) is calculated as follows, with a similar process for an arbitrary value \(\alpha_t\).

\[ \alpha_2 = (\alpha_1 P)_k \mathbb{P}(X_2 | Z_2 = k) \]

The \(P\) symbol corresponds to a symmetric 2x2 transition matrix where the first row is \((0.9, 0.1)\) and the second row is \((0.1, 0.9)\).

To compute the backwards probabilities, we compute the following \(\beta_{tk} = \mathbb{P}(X_{t+1}, ... , X_T; Z_t = k)\), and then the posterior distribution for each state \(Z_t\) is given by the following:

\[ \mathbb{P}(Z_t = k| X_1, ..., X_T) = \alpha_{tk} \beta_{tk} / \sum_{k}\alpha_{tk} \beta_{tk} \]

The interpretation of this above graph seems quite clear at first blush - the “hidden” state of the world throughout 2008 is indeed the “irrational” one, marked by the relative success of the univariate CAViaR model. As perhaps with all research, this work generates many more questions than it answers. There are several next steps that are worth exploring.

  • Adding more lagged terms into the HMM, or at least tinkering with the transition probability to understand the sensitivity of these parameters to the outcome
  • Exploring what happens if the HMM were fit to all 8 candidate models, or using a Neural Network or Random Forest to find the hidden state
  • Considering the implicit assumption that these forecasts are based on an asymmetric loss function (see the Appendix), and finding a way to weigh the consideration that an overprediction is a fairly clear indication that the world is not in that state

Changepoint Detection

The second question is to understand shifts in the economy using a changepoint detection algorithm:

  1. Using a set of ETFs, perform Principal Component Analysis at \(T\) many points for \(M\) many factors - \(f_{m,t}\)
  2. At each time point, add the vectors together to get a resultant: \(\sum_{m=1}^M f_{m,t} = r_t\), giving \(r_1, r_2, ..., r_T\).
  3. Starting with an arbitrary reference point \(t_0\) with associated \(r_0\) resultant, measure the angle between resultants calculated at different time steps \(r_{t}\)

\[ \theta_t = \arccos \left(\frac{r_{0} \cdot r_{t}}{||r_{0}|| ||r_{t}||} \right) \]

The angle \(\theta\) could be plotted over time, and changepoints could be detected using Monte Carlo simulation, because PCA transformations are non-linear, so calculating an analytical density from the transformed data is intractable. Moreover, the data fed into the PCA transformation is non-normal, which further supports the notion of using Monte Carlo simulation to establish reasonable estimates of uncertainty for detected changepoints. As with the first line of reasoning, there would certainly be interesting challenges, particularly in creating crisp null and alternative hypotheses.

Data Used

The response variable used in this analysis is SPY, which is an exchange-traded fund that aims to track the performance of the S&P 500, which is discussed above. It is broadly used as a bellwether of the U.S. economy, and has the advantage of avoiding survivorship bias - while an individual stock might go bankrupt or merge with another, it is reasonable to assume that these issues do not apply with an ETF.

Following this logic, there are several classes of response variables used in this analysis. The first group is a set of U.S. sector ETFs obtained from Seeking Alpha (NA 2020). As with the response variable, these ETFs were publicly traded throughout the Great Recession of 2008.

  1. Utilities (XLU)
  2. Consumer Staples (XLP)
  3. Healthcare (XLV)
  4. Technology (XLK)
  5. Consumer Discretionary (XLY)
  6. Industrial (XLI)
  7. Financial Services (XLF)
  8. Basic Materials (XLB)
  9. Energy (XLE)

The second group for this analysis is bond ETFs. Like the previous two groups, these ETFs potentially contain forward-looking information about the stock market. These ETFs were chosen because they were the first fixed-income ETFs available in the United States, and had enough history for this paper (NA 2017).

  1. iShares 1-3 Year Treasury Bond Fund (SHY)
  2. iShares 7-10 Year Treasury Bond Fund (IEF)
  3. iShares 20+ Year Treasury Bond Fund (TLT)
  4. iShares iBoxx $ Investment Grade Corporate Bond ETF (LQD)

Results

U.S. ETFs Results for 2007 - 2008

A natural criticism of the above fits are that the data is noisy. A complication of this analysis is the fact that there isn’t necessarily anything to “pin” the data to, because the problem is unsupervised. As such, I think a decent way to picking the wheat from the chaff (or the signal from the noise) is to apply some smoothing filters to the above data. Two options to do so are the moving average smoother and the Lowess smoothers.

In the above plot, I applied a few filters, namely the moving average filter with equal weights for plus/minus 5 days and 10 days as well as the Lowess with a weight of \(f = 1/6\) for higher levels of precision. Below are the specifications for moving average with 5 and 10 days, where \(x_t\) is the angle between the resultants.

\[ m_{t,5} = \sum_{j =-5}^5 \frac{1}{11} x_{t-j}, m_{t,10} = \sum_{j =-10}^{10} \frac{1}{21} x_{t-j} \]

The Lowess smoother is a smoother that per Shumway and Stoffer (Shumway and Stoffer 2016), is a technique "based on k-nearest neighbors regression, wherein one uses only the data \([x_{t-k/2}, ... , x_t, ..., x_{t+k/2}]\) to predict the true value of \(x_t\). Based on a visual inspection of the data, it appears that a more precise estimator was in order, so the Lowess function only uses 1/6th of the data.

There are some interesting trends that bear discussion. While some of macroeconomics may appear to be little more than a crystal ball, or a science based upon strong priors, I don’t believe that to be the case here. In the above graph, the angle between resultant vectors calculated from baskets of equity exchange-traded funds (ETFs) for different sectors of the U.S. economy point, almost as a leading indicator, towards the once-in-a-lifetime tumult that was about to grip the U.S. and global financial markets. Indeed, in the graph above, the angle of the resultant seems to stabilize for the month of August 2008, which corresponds roughly to the 400 – 425 trading days since the reference point at the end of 2006. This is before Lehman Brothers declared bankruptcy, before AIG was bailed out, and before Congress passed TARP. It remains to be seen whether this is coincidental or whether there really is a leading indicator here, but I believe the question is worth asking and worth exploring further.

From a statistical perspective, the most important fact about these trends is that the algorithm that produces them, namely PCA, is an unsupervised learning algorithm. At no point in this work is there a model of any kind trying to predict gyrations in the S&P500 or the Dow Jones or the real economy. Indeed, remember that these principal components are based upon sector ETFs, things like Energy, Consumer Staples, and Utilities, which in turn are based upon individual stocks - companies like Exxon, Capital One, General Electric, and Amazon. These stock prices may seemingly be enigmatic and noisy, but ironically they look this way because according to economic theory, they are likely to contain all the relevant information about their company as determined by market participants (Malkiel 2003). What if, in all of their foresight, they saw the most cataclysmic economic event of our time before it happened, without even aiming to do so?

While future work in this area would benefit greatly from a variational autoencoder to be able to figure out what is exactly a meaningful change, it may also benefit from having additional data fed into it.

Appendix

U.S. ETFs Results for the 2011 - 2012

U.S. ETFs Results for the 2013 - 2014

U.S. ETFs Results for the 2015 - 2016

U.S. + Bond ETF Results for 2007 - 2008

U.S. + Bond ETF Results for the 2011 - 2012

U.S. + Bond ETF Results for the 2013 - 2014

U.S. + Bond ETF Results for the 2015 - 2016

Univariate CAViaR Model Specifications

However, work needed to be done to align the diffusion index model with the CAViaR model, which is defined below. The following variables are required for use in the CAViaR model. For ease of notation, these are sourced directly from the Engle and Manganelli 2004 CAViaR paper (Engle and Manganelli 2004), with some added description:

  • \((y_t)_{t=1}^T\) is a “vector of portfolio returns”
  • \(\theta\) is the “probability associated with VaR” (a 5% VaR would mean \(\theta = 0.05\))
  • \(\boldsymbol{x_t}\) is a “vector of time \(t\) observable variables”
  • \(f_t(\boldsymbol{\beta}) \equiv f_t(\boldsymbol{x_{t-1}, \boldsymbol{\beta_\theta}})\) is the “time \(t\)”, “\(\theta\) quantile of the distribution of portfolio returns formed at time \(t-1\)

The authors then describe a “generic CAViaR specification” as follows:

\[ f_t(\boldsymbol{\beta}) = \beta_0 + \sum_{i=1}^q \beta_i f_{t-1}(\boldsymbol{\beta}) + \sum_{j=1}^r \beta_{q+j} l(\boldsymbol{x_{t-j}}) \]

What is interesting about the general setup is that there are two main components to the model - lagged observed variables (represented by \(l\)) and lagged values of unknown parameters, which in the specification below is used as moving average terms. As such, it is reasonable to generalize the specifications below as nonlinear ARMA models where \(y_{t-1}\) terms refer to previous returns, whereas \(f_{t-1}(\beta_1)\) terms refer to previous predictions.

Adaptive CAViaR Model

Consider the following model:

\[ f_t(\beta_1) = f_{t-1}(\beta_1) + \beta_1\left[\left(1+ \exp(G[y_{t-1} - f_{t-1}(\beta_1)]) \right)^{-1} - \theta \right] \]

Following Engle and Manganelli’s 2004 paper, we choose \(G = 10\), so that is what is used in the results section of this paper. The authors state the reason for the seemingly arbitrary choice is that while “the parameter G itself could be estimated; however, this would go against the spirit of this model, which is simplicity”. Previous sensitivity analysis showed that running the adaptive model with \(G = 5\) did not materially affect the VaR predictions - the accuracy was not changed. While this model is nonlinear in G and total scale invariance in \(G\) would be surprising given the nonlinear relationship, the fact that the other fitted parameters likely adjusted is not surprising.

Symmetric Absolute Value CAViaR Model

Below is the symmetric absolute value CAViaR model:

\[ f_t(\boldsymbol{\beta}) = \beta_1 + \beta_2f_{t-1}(\boldsymbol{\beta}) + \beta_3|y_{t-1}|. \]

Asymmetric Slope CAViaR Model

Below is the asymmetric slope CAViaR model:

\[ f_t(\boldsymbol{\beta}) = \beta_1 + \beta_2f_{t-1}(\boldsymbol{\beta}) + \beta_3(y_{t-1})^+ + \beta_4(y_{t-1})^-. \]

Indirect GARCH (1,1) CAViaR Model

Below is the Indirect GARCH (1,1) model:

\[ f_t(\boldsymbol{\beta}) = (\beta_1 + \beta_2f_{t-1}^2(\boldsymbol{\beta}) + \beta_3y_{t-1}^2)^{1/2}. \]

Multivariate CAViaR Model Specifications

The multivariate CAViaR model takes inspiration from the models described above in several specifications, as mentioned in the original specifications. The general model form looks like the specification below:

\[ f_t(\boldsymbol{\beta}) = \beta_0 +\sum_{i=1}^p \beta_i y_{t-i} + \sum_{j=1}^m \beta_{j+p} f_{j,t-1} + e_t. \]

As with the univariate CAViaR model, the object of interest is a \(\theta\) percentile return and the model is fit iteratively to minimize the loss function on the training data. However, there are some notable differences between the univariate model and the multivariate model. First, there are no moving average terms (lagged error terms) - the reasoning for this is because this model aims for a clear economic interpretation, and crisp interpretations of MA models are harder to create. Also, moving average models require recursive estimation since error terms are not observed, and so developing a method to work with these errors in a robust regression framework is challenging.

Second, in some of the specifications below, there are lagged return variables. This is similar to the univariate CAViaR specification, though there is often more than 1 lag as in the univariate model - there are \(p\) lags in the dataset. Third, in all of the specifications below, there are \(m\) diffusion indices used in each model lagged by one time step to avoid look-ahead bias.

Multivariate CAViaR: No Lags Model

\[ f_t(\boldsymbol{\beta}) = \beta_0 +\sum_{j=1}^m \beta_{j} f_{j,t-1} + e_t \]

Multivariate CAViaR with Autoregressive Terms Added

\[ f_t(\boldsymbol{\beta}) = \beta_0 +\sum_{i=1}^p \beta_i y_{t-i} + \sum_{j=1}^m \beta_{j+p} f_{j,t-1} + e_t \]

Multivariate CAViaR with Symmetric Absolute Value Autoregressive Terms Added

\[ f_t(\boldsymbol{\beta}) = \beta_0 +\sum_{i=1}^p \beta_i |y_{t-i}| + \sum_{j=1}^m \beta_{j+p} f_{j,t-1} + e_t \]

Multivariate CAViaR with Asymmetric Slope Autoregressive Terms Added

\[ f_t(\boldsymbol{\beta}) = \beta_0 +\sum_{i=1}^p \beta_i (y_{t-i})_+ + \sum_{j=p+1}^{2p} \beta_i (y_{t-i})_- + \sum_{k=1}^m \beta_{k+2p} f_{k,t-1} + e_t \]

Fitting the Models

To fit the models, an optimal value of \(m\) diffusion indices and \(p\) autoregressive terms are added (or \(2p\) in the case of the asymmetric slope model). The optimal values of these parameters are determined using a validation dataset. In all of the runs below, there are a total of 5 years of trading days, or about 1,260 days assuming 252 trading days a year. The adjusted closing prices are logged and differenced, shortening the dataset by one. After doing this, the last 250 data points are reserved as test data, and the 250 data points before that are used as a validation set. Measured by the loss function written out below, the values of \(p\) and \(m\) that minimize losses are chosen and the optimal model is refit over both the training and the validation data combined and then evaluated on the test data. Note that there is an optimal model which is chosen for each of the four multivariate CAViaR specifications described above, so there are 4 optimal sets of \(p\) and \(m\) chosen for each set of models. Thus, there are 8 models compared on the test data - 4 univariate CAViaR models and 4 multivariate CAViaR models.

From the CAViaR paper, the \(\theta\)th regression quantile is defined as any \(\boldsymbol{\hat{\beta}}\) that solves the following loss function:

\[ \overset{argmin}\beta \frac{1}{T}\sum_{t=1}^T [\theta - I(y_t < f_t(\boldsymbol{\beta}))][y_t - f_t(\boldsymbol{\beta})] \]

Code

The code can be found at the location listed below in the “STAT_771_Class_Project.Rmd” file.

https://github.com/stevenmoen/stat_771_final_project

Big HMM Function

Literature Cited

Engle, Robert F, and Simone Manganelli. 2004. “CAViaR.” Journal of Business & Economic Statistics 22 (4): 367–81. https://doi.org/10.1198/073500104000000370.

Holton, Glyn A. 2014. “History of VaR - Value-at-Risk: Theory and Practice.” https://www.value-at-risk.net/history-of-value-at-risk/.

Kassambara, Alboukadel. 2018. “Transform Data to Normal Distribution in R: Easy Guide - Datanovia.” https://www.datanovia.com/en/lessons/transform-data-to-normal-distribution-in-r/.

Longerstaey, Jacques, and Martin Spencer. 1996. “RiskMetrics - Technical Document.” J.P. Morgan/Reuters. http://www.jpmorgan.com/RiskManagement/RiskMetrics/RiskMetrics.html.

Malkiel, Burton Gordon. 2003. A random walk down Wall Street : the time-tested strategy for successful investing. New York: W.W. Norton.

NA. 2017. “iShares Institutional Guide to Bond ETFs.” https://www.complianceweek.com/download?ac=5780.

———. 2020. “Sector ETFs | Seeking Alpha.” https://seekingalpha.com/etfs-and-funds/etf-tables/sectors.

Portnoy, Stephen. 1991. “Asymptotic behavior of regression quantiles in non-stationary, dependent cases.” Journal of Multivariate Analysis 38 (1): 100–113. https://doi.org/https://doi.org/10.1016/0047-259X(91)90034-Y.

Richardson, Matthew P., Jacob (Kobi) Boudoukh, and Robert F Whitelaw. 2005. “The Best of Both Worlds: A Hybrid Approach to Calculating Value at Risk.” SSRN Electronic Journal. https://doi.org/10.2139/ssrn.51420.

Shumway, Robert, and David Stoffer. 2016. Time Series Analysis and Its Applications With R Examples Fourth Edition. Fourth. Springer. https://www.stat.pitt.edu/stoffer/tsa4/tsa4.pdf.

Stephens, Matthew. 2018. “HMM example.” https://stephens999.github.io/fiveMinuteStats/hmm.html.

Stock, James H, and Mark W Watson. 2002a. “Macroeconomic Forecasting Using Diffusion Indexes.” Journal of Business & Economic Statistics 20 (2): 147–62. https://doi.org/10.1198/073500102317351921.

———. 2002b. “Forecasting Using Principal Components from a Large Number of Predictors.” Journal of the American Statistical Association 97 (460): 1167–79. http://www.jstor.org/stable/3085839.

LS0tCnRpdGxlOiAnU1RBVCA3NzEgLSBQcm9qZWN0IEZpbmFsIERyYWZ0JwphdXRob3I6ICJTdGV2ZW4gTW9lbiIKZGF0ZTogIlN1bmRheSwgTm92ZW1iZXIgMjl0aCwgMjAyMCIKb3V0cHV0OgogIHBkZl9kb2N1bWVudDogZGVmYXVsdAogIGh0bWxfbm90ZWJvb2s6IGRlZmF1bHQKYmlibGlvZ3JhcGh5OiBzdGF0Xzc3MV9wcm9qZWN0X2JpYi5iaWIKbGluay1jaXRhdGlvbnM6IHllcwotLS0KCmBgYHtyIGdsb2JhbF9vcHRpb25zLCBpbmNsdWRlPUZBTFNFfQprbml0cjo6b3B0c19jaHVuayRzZXQoZmlnLnBhdGg9J0ZpZ3MvJywgZWNobz1GQUxTRSwgd2FybmluZz1GQUxTRSwgbWVzc2FnZT1GQUxTRSwgY2FjaGUgPSBUUlVFKQpgYGAKCiMgQmFja2dyb3VuZCBhbmQgTW90aXZhdGlvbgoKTXkgTS5TLiB0aGVzaXMgYXQgdGhlIFVuaXZlcnNpdHkgb2YgQ2hpY2FnbyBkZXZlbG9wZWQgYSBub3ZlbCBtZXRob2QgdG8gdW5kZXJzdGFuZCBhbmQgbWVhc3VyZSB2YWx1ZS1hdC1yaXNrLCBhIGNvbW1vbmx5IGFjY2VwdGVkIG1ldGhvZCB0byBtZWFzdXJlIGRvd25zaWRlIHJpc2suIFRoZSBtZXRyaWMgaXMgdW5kZXJzdG9vZCBhcyBmb2xsb3dzOiBhIG9uZS1kYXkgMSUgVmFSIG9mIC0xMCBtaWxsaW9uIGRvbGxhcnMgZm9yIGEgcG9ydGZvbGlvIG1lYW5zIHRoYXQgdGhlIHBvcnRmb2xpbyB3aWxsIGxvc2UgYXQgbGVhc3QgMTAgbWlsbGlvbiBkb2xsYXJzIG9mIGl0cyB2YWx1ZSBvbiB0aGUgMSUgd29yc3QgdHJhZGluZyBkYXlzLiBBIG1ham9yIGFkdmFudGFnZSBvZiBWYVIgaXMgdGhhdCBpdCBkaXN0aWxscyBhIGRpc3RyaWJ1dGlvbiBvZiByZXR1cm5zIGludG8gb25lIG51bWJlci4gQXMgc3VjaCwgVmFSIGlzIG9mdGVuIHVzZWQgaW4gc3RyZXNzIHRlc3RpbmcgYnkgcmVndWxhdG9yeSBhZ2VuY2llcyBbQEhvbHRvbjIwMTRdLiAKClRoZXJlIGhhdmUgYmVlbiBtYW55IHBvcHVsYXIgYXBwcm9hY2hlcyBpbiB0aGUgbGl0ZXJhdHVyZSB0byBlc3RpbWF0ZSBWYVIgc3VjaCBhcyBtb2RlbGluZyB0aGUgdG90YWwgZGlzdHJpYnV0aW9uIG9mIHJldHVybnMgW0BMb25nZXJzdGFleTE5OTZdIGFuZCB1c2luZyBhIHNlbWlwYXJhbWV0cmljIG9yIGEgbm9ucGFyYW1ldHJpYyBoaXN0b3JpY2FsIHNpbXVsYXRpb24gW0BSaWNoYXJkc29uMjAwNV0uIEVuZ2xlIGFuZCBNYW5nYW5lbGxpIGFyZ3VlIGluIGEgMjAwNCBwYXBlciBbQEVuZ2xlMjAwNF0gdGhhdCB3aGlsZSBtb2RlbGluZyB0aGUgZW50aXJlIGRpc3RyaWJ1dGlvbiBpcyBsaWtlbHkgdG9vIHNpbXBsaXN0aWMsIG5vbnBhcmFtZXRyaWMgbWV0aG9kcyBpbiB0aGUgb3RoZXIgY2FtcCBhcmUgdXN1YWxseSBjaG9zZW4gZm9yIOKAnGVtcGlyaWNhbCBqdXN0aWZpY2F0aW9ucyByYXRoZXIgdGhhbiBvbiBzb3VuZCBzdGF0aXN0aWNhbCB0aGVvcnnigJ0uIFRvIGJhbGFuY2UgdGhlc2UgYXBwcm9hY2hlcywgdGhleSBwcm9wb3NlIGEgZnJhbWV3b3JrIGNhbGxlZCBDQVZpYVIgdGhhdCBkaXJlY3RseSBmb3JlY2FzdHMgdGhlIFZhUiBxdWFudGlsZSB1c2luZyBhIGNvbmRpdGlvbmFsIGF1dG9yZWdyZXNzaXZlIHF1YW50aWxlIHNwZWNpZmljYXRpb24uIFRoaXMgYXBwcm9hY2ggYnVpbGRzIHVwb24gdGhlIHN0YXRpc3RpY2FsIGxpdGVyYXR1cmUgdGhhdCBleHRlbmRzIGxpbmVhciBxdWFudGlsZSBtb2RlbHMgdG8gc2V0dGluZ3MgYW1lbmFibGUgdG8gZmluYW5jaWFsIG1vZGVsaW5nLCBzdWNoIGFzIHdpdGggaGV0ZXJvc2tlZGFzdGljIGFuZCBub25zdGF0aW9uYXJ5IGVycm9yIGRpc3RyaWJ1dGlvbnMgW0BQb3J0bm95MTk5MV0uCgpNeSB0aGVzaXMgZXh0ZW5kcyB0aGUgbW9kZWwgYmV5b25kIGEgdW5pdmFyaWF0ZSBzZXR0aW5nIGludG8gYSBtdWx0aXZhcmlhdGUgc2V0dGluZyB1c2luZyB0aGUgZGlmZnVzaW9uIGluZGV4IG1vZGVsLCBvcmlnaW5hbGx5IGRldmVsb3BlZCBieSBTdG9jayBhbmQgV2F0c29uIGZvciBwcmVkaWN0aW5nIGNvbmRpdGlvbmFsIG1lYW5zIFtAU3RvY2syMDAyOyBAU3RvY2syMDAyYV0uIE15IG1vZGVsIHVzZXMgZXhjaGFuZ2UtdHJhZGVkIGZ1bmRzIChFVEZzKSBhcyBleHBsYW5hdG9yeSB2YXJpYWJsZXMgdGhhdCBhcmUgY29tYmluZWQgaW50byBwcmluY2lwYWwgY29tcG9uZW50IHZlY3RvcnMgYXQgdGhlIGZvcmVjYXN0IG9yaWdpbi4gQ29tYmluaW5nIHRoZXNlIHByaW5jaXBhbCBjb21wb25lbnQgdmVjdG9ycyB3aXRoIHRyYW5zZm9ybWF0aW9ucyBvZiBsYWdnZWQgYXV0b3JlZ3Jlc3NpdmUgcmVzcG9uc2UgdmFyaWFibGVzIHByb2R1Y2VzIHNpbWlsYXIgcHJlZGljdGl2ZSBhY2N1cmFjeSBkdXJpbmcgcGVyaW9kcyBvZiByZWxhdGl2ZWx5IGxvdyB2b2xhdGlsaXR5ICh3aGVuIGNvbXBhcmVkIHRvIHRoZSBDQVZpYVIgbW9kZWwpIGFsb25nIHdpdGggbW9yZSBpbnNpZ2h0IGludG8gdGhlIGRyaXZlcnMgb2YgdGhlIGNoYW5nZXMgaW4gdGhlIHJlc3BvbnNlIHZhcmlhYmxlLgoKIyBJbnRlbmRlZCBXb3JrCgpBcyBlbmNvdXJhZ2luZyBhcyB0aGUgcmVzdWx0cyB3ZXJlIGZyb20gbXkgdGhlc2lzLCB0d28gaW1wb3J0YW50IHF1ZXN0aW9ucyByZW1haW5lZCB1bmFuc3dlcmVkLiBUaGUgZmlyc3QgaXMgd2hldGhlciBzb21lIHNvcnQgb2YgbWl4dHVyZSBtb2RlbCB3b3VsZCBiZSBhcHByb3ByaWF0ZSwgdGhhdCBpcywgYWltaW5nIHRvIHVzZSB0aGUgYmFza2V0IG9mIEVURnMgZHVyaW5nIGdvb2QgdGltZXMsIGFuZCB1c2UgdGhlIENBVmlhUiBBUk1BIHNwZWNpZmljYXRpb24gZHVyaW5nIGJhZCB0aW1lcy4gVGhlIGFwcHJvYWNoIG9mIHVzaW5nIEVURnMgYWxsb3dzIGEgcHJlZGljdGlvbiBiYXNlZCBvbiBmb3J3YXJkLWxvb2tpbmcgZXhwZWN0YXRpb25zIG9mIGZ1bmRhbWVudGFsIGZhY3RvcnMuIEluZGVlZCwgRVRGcyBhcmUganVzdCBiYXNrZXRzIG9mIGluZGl2aWR1YWwgc3RvY2tzIG9yIGJvbmRzLCBhbmQgdGhvc2Ugc2VjdXJpdGllcyBhcmUgKGluIHRoZW9yeSkgYmFzZWQgb24gcmF0aW9uYWwgZXhwZWN0YXRpb25zIGFib3V0IGZ1dHVyZSByZXNvdXJjZXMsIG1hcmtldCBjb25kaXRpb25zLCBldGMgLSB0aGUgbWljcm9mb3VuZGF0aW9ucyBvZiB3aGF0IGRyaXZlcyBvdXIgZWNvbm9teS4gVGhlIEFSTUEgc3BlY2lmaWNhdGlvbiwgd2hpbGUgcHJhY3RpY2FsbHkgYW5kIHN0YXRpc3RpY2FsbHkgc291bmQsIGlzIGNvbnRyYWRpY3RlZCBieSBlY29ub21pYyB0aGVvcnkgYW5kIHByYWN0aWNlIC0gdGhlIHdlYWsgZm9ybSBvZiB0aGUgZWZmaWNpZW50IG1hcmtldCBoeXBvdGhlc2lzIHN0YXRlcyB0aGF0IGl0IGlzIGltcG9zc2libGUgdG8gZm9yZWNhc3QgZnV0dXJlIHZhbHVlcyBvZiBhc3NldCBwcmljZXMgdXNpbmcgcGFzdCB2YWx1ZXMuIEJ1dCBwZXJoYXBzIHRoaXMgdmlldyBpcyBpbmNvbXBsZXRlLiAKClRvIGNvbWJpbmUgdGhlc2UgaWRlYXMsIEkgd2lsbCBmaXQgYSBIaWRkZW4gTWFya292IE1vZGVsIHRvIGluZmVyIHRoZSBzdGF0ZSBvZiB0aGUgd29ybGQgLSB0aGUgInJhdGlvbmFsIiBvbmUsIG9yIHRoZSAiaXJyYXRpb25hbCIgb25lLiBHaXZlbiB0aGUgaGlnaGx5IG5vbi1ub3JtYWwgbmF0dXJlIG9mIGZpbmFuY2lhbCBkYXRhLCBJIHN1c3BlY3QgdGhlcmUgd291bGQgYmUgbWFueSBpbnRlcmVzdGluZyBzdGF0aXN0aWNhbCBhbmQgY29tcHV0YXRpb25hbCBjaGFsbGVuZ2VzIHRoYXQgd291bGQgYXJpc2Ugd2l0aCB0aGlzIGFwcHJvYWNoLiBJbiBhZGRpdGlvbiwgaXQgaXMgbGlrZWx5IHdvcnRoIGV4cGxvcmluZyBhbHRlcm5hdGl2ZSBlbnNlbWJsZSBtZXRob2RzIHRvIGZ1cnRoZXIgcHJvYmUgaW50byB0aGUgc2VlbWluZ2x5IGVuaWdtYXRpYyBuYXR1cmUgdGhhdCBwZXJ2YWRlcyBmaW5hbmNpYWwgdGltZSBzZXJpZXMuCgpXaGVuIEkgaW1wbGVtZW50IHRoaXMsIHRoZSAicmF0aW9uYWwiIHN0YXRlIG9mIHRoZSB3b3JsZCB3aWxsIHJlZmVyIHRvIHRoZSBwcmVkaWN0aW9ucyBvZiBvbmUgb2YgdGhlIG11bHRpdmFyaWF0ZSBDQVZpYVIgbW9kZWxzIHdoZXJlIGFzIHRoZSAiaXJyYXRpb25hbCIgc3RhdGUgb2YgdGhlIHdvcmxkIHdpbGwgcmVmZXIgdG8gb25lIG9mIHRoZSBwcmVkaWN0aW9ucyBmcm9tIHRoZSB1bml2YXJpYXRlIENBVmlhUiBtb2RlbHMuIE9uZSB3YXkgdG8gcG9zc2libHkgaW1wbGVtZW50IHRoaXMgaXMgdG8gc2F5IHRoYXQgaWYgdGhlIGxvc3NlcyBmcm9tIHRoZSBtdWx0aXZhcmlhdGUgbW9kZWxzIGFyZSBsb3dlciwgdGhlbiB0aGUgSE1NIHdpbGwgbGVhbiB0b3dhcmRzIHRoZSByYXRpb25hbCBzdGF0ZSBvZiB0aGUgd29ybGQsIG90aGVyd2lzZSwgaXQgd2lsbCBsZWFuIHRvd2FyZHMgdGhlIG90aGVyIHN0YXRlLgoKCmBgYHtyfQojIFJlYWQgaW4gcmVsZXZhbnQgbGlicmFyaWVzCmxpYnJhcnkobWljcm9iZW5jaG1hcmspCmxpYnJhcnkoZGF0YS50YWJsZSkKbGlicmFyeShxdWFudG1vZCkKbGlicmFyeShnZ3Bsb3QyKQpsaWJyYXJ5KHRzZXJpZXMpCmxpYnJhcnkoem9vKQpsaWJyYXJ5KG1hZ3JpdHRyKQpsaWJyYXJ5KGRwbHlyKQpsaWJyYXJ5KGthYmxlRXh0cmEpCmxpYnJhcnkoZm9ybWF0dGFibGUpCmxpYnJhcnkocXVhbnRyZWcpCmxpYnJhcnkoTVRTKQpsaWJyYXJ5KHBsb3QzRCkKbGlicmFyeShjaXRyKQpsaWJyYXJ5KGZvcm1hdHRhYmxlKQpsaWJyYXJ5KGZHYXJjaCkKbGlicmFyeShpc21ldikKbGlicmFyeShldmQpCmxpYnJhcnkoTGFwbGFjZXNEZW1vbikKCgojIFNldCB1cCB3b3JraW5nIGRpcmVjdG9yeQpzb3VyY2UoJ34vRG9jdW1lbnRzL0dpdEh1Yi9DYXZpYVIvY2F2aWFyX1NNLlInKQpgYGAKCgoKCgpgYGB7cn0KIycgQSBmdW5jdGlvbiB0byBpbnB1dCB0aGUgVmFSIGZpbGVzLCBwbG90IHRoZW0gYW5kIGdlbmVyYXRlIHRhYmxlcwojJwojJyBAcGFyYW0gZmlsZV9wYXRoIC0gZmlsZSBwYXRoIHRvIHVzZQojJyBAcGFyYW0gZmlsZW5hbWUgLSBuYW1lIG9mIHRoZSBmaWxlCiMnIEBwYXJhbSB0YXUgLSBxdWFudGlsZSB0byB1c2UKIycgQHBhcmFtIHJlc3BfdmFyIC0gcmVzcG9uc2UgdmFyaWFibGUgdG8gdXNlIGluIHRoZSBwbG90CiMnIEBwYXJhbSBudGVzdCAtIG51bWJlciBvZiB0ZXN0IHBvaW50cwojJyBAcGFyYW0gY25faW5wdXQgLSBjb2x1bW4gbmFtZSBpbnB1dHMKIycKIycgQHJldHVybiAtIGEgbGlzdCBvZiB0aGUgeHRzIGZpbGUsIHRoZSBwbG90LCB0aGUgbG9zcyBsaXN0LCBhbmQgdGFibGVzCiMnIEBleHBvcnQgLSBhIHBsb3QgYW5kIHRhYmxlcwojJwojJyBAZXhhbXBsZXMgLSB0ZXN0ID0gdmFyX2lucHV0X2Rpc3AoIi9Vc2Vycy9zdGV2ZW5tb2VuL0RvY3VtZW50cy9HaXRIdWIvQ0FWaWFSX01TX3RoZXNpcy9EYXRhX0V4cG9ydC9TUFlfVVNfRVRGX3J1bnMvIiwidmFyXzFwY18yMDA4X3VzX2V0Zi5jc3YiLCAwLjAxKQp2YXJfaW5wdXRfZGlzcCA9IGZ1bmN0aW9uKGZpbGVfcGF0aCwgZmlsZW5hbWUsIHRhdSwgcmVzcF92YXIgPSAiU1BZIiwgbnRlc3QgPSAyNTAsIGNuX2lucHV0ID0gYygiU1BZIiwgIk5vIEFSIiwgIkFSIiwgIlNBViBBUiIsICJBUyBBUiIsICJTQVYiLCAiQXN5bS4gU2xvcGUiLCAiSW5kLiBHQVJDSCIsICJBZGFwdGl2ZSIpLCBwcmludF9ncmFwaCA9IDEsIHByaW50X212X3RhYmxlID0gMSwgcHJpbnRfdXZfdGFibGUgPSAxLCBwcmludF9vcHRfcGFyYW0gPTEpewogICMgSW1wb3J0IGRhdGEKICBwbG90X21hdCA9IHJlYWQuY3N2KHBhc3RlMChmaWxlX3BhdGgsZmlsZW5hbWUpLCBzZXAgPSAiLCIsIGhlYWRlciA9IFQsIHN0cmluZ3NBc0ZhY3RvcnMgPSBGQUxTRSkKICAjIEZpeCBkYXRlIGZvcm1hdAogIHBsb3RfbWF0JEluZGV4ID0gYXMuRGF0ZShwbG90X21hdCRJbmRleCkKICAjIENvbnZlcnQgdG8gYW4geHRzCiAgcGxvdF9tYXQgPSB4dHMocGxvdF9tYXRbLC0xXSwgb3JkZXIuYnkgPSBwbG90X21hdFssMV0pCiAgIyBGaXggY29sdW1uIG5hbWVzCiAgY29sbmFtZXMocGxvdF9tYXQpIDwtIGNuX2lucHV0CiAgIyBQbG90IGV2ZXJ5dGhpbmcKICBpZiAocHJpbnRfZ3JhcGggPT0gMSl7CiAgICBwbHRfZGF0YShwbG90X21hdCwgdGF1ID0gdGF1LCByZXNwX3ZhciA9IHJlc3BfdmFyLCBudGVzdCA9IG50ZXN0KQogIH0KICAjIENhbGN1bGF0ZSBsb3NzZXMKICBsX2xpc3QgPSBnZW5fbG9zc190ZXN0KHBsb3RfbWF0LCB0YXUgPSB0YXUpCiAgIyBQdXQgaW50byB0YWJsZXMKICBkZiA9IGFzLmRhdGEuZnJhbWUocmJpbmQobF9saXN0W1sxXV0sIGxfbGlzdFtbMl1dKSkKICAjIENhbGN1bGF0ZSBpbml0YWwgYW5kIGVuZGluZyB0aW1lIHZhbHVlCiAgc3RhcnQgPSBpbmRleChwbG90X21hdClbMV0KICBlbmQgPSBpbmRleChwbG90X21hdClbbnJvdyhwbG90X21hdCldCiAgIyBBZGQgcm93L2NvbHVtbiBuYW1lcwogIGNvbG5hbWVzKGRmKSA8LSBjb2xuYW1lcyhwbG90X21hdFssLTFdKQogIHJvd25hbWVzKGRmKSA8LSBjKCJMb3NzZXMiLCAiVmFSIEJyZWFrIFJhdGUiKQogICMgRWRpdHMgb24gNS4xMi4yMDIwIC0gZGl2aWRlIHRoZSB0YWJsZSBpbnRvIDIKICBtdl9kZiA9IGRmWywxOjRdCiAgdXZfZGYgPSBkZlssNTo4XQogIGlmIChwcmludF9tdl90YWJsZSA9PSAxKXsKICAgIHByaW50KGtuaXRyOjprYWJsZShtdl9kZiwgZGlnaXRzID0gMyksIGZvcm1hdCA9ICdwYW5kb2MnKQogICAgY2F0KCJcbiIpCiAgfQogIGlmIChwcmludF91dl90YWJsZSA9PSAxKXsKICAgIHByaW50KGtuaXRyOjprYWJsZSh1dl9kZiwgZGlnaXRzID0gMyksIGZvcm1hdCA9ICdwYW5kb2MnKQogICAgY2F0KCJcbiIpCiAgfQogICMgUHJpbnQgdGhlIG9wdGltYWwgcGFyYW1ldGVycwogIGlmIChwcmludF9vcHRfcGFyYW0gPT0gMSl7CiAgICAjIEltcG9ydCB0aGUgZGF0YSBmcmFtZQogICAgb3B0X3BtID0gcmVhZC5jc3YocGFzdGUwKGZpbGVfcGF0aCxwYXN0ZTAoc3Vic3RyKGZpbGVuYW1lLCAxLCBuY2hhcihmaWxlbmFtZSktNCksIl9wbS5jc3YiKSksIHNlcCA9ICIsIiwgaGVhZGVyID0gVCwgc3RyaW5nc0FzRmFjdG9ycyA9IEZBTFNFKQogICAgb3B0X3BtIDwtIG9wdF9wbVssLTFdCiAgICAjIEFzc2lnbiBuYW1lcwogICAgcm93bmFtZXMob3B0X3BtKSA8LSBjbl9pbnB1dFsyOjVdCiAgICBjb2xuYW1lcyhvcHRfcG0pIDwtIGMoIk9wdGltYWwgTSIsICJPcHRpbWFsIFAiKQogICAgIyBGaXggdGhlIHJvdyBhbmQgY29sdW1uIG5hbWVzCiAgICAjIEZvcm1hdCBuaWNlbHkKICAgICMgcHJpbnQob3B0X3BtICU+JSBrYWJsZShjYXB0aW9uID0gIk9wdGltYWwgTnVtYmVyIG9mIERpZmZ1c2lvbiBJbmRpY2VzIChtKSBhbmQgTGFncyAocCkgZm9yIERpZmZlcmVudCBNb2RlbHMiLCBkaWdpdHMgPSAwKSAlPiUga2FibGVfc3R5bGluZygic3RyaXBlZCIsIGZ1bGxfd2lkdGggPSBGKSAlPiUga2FibGVfc3R5bGluZygpICU+JSBmb290bm90ZShnZW5lcmFsID0gIlRoZSBNViBDQVZpYVIgbW9kZWwgZG9lc24ndCBoYXZlIGFuIG9wdGltYWwgdmFsdWUgZm9yIHAgYmVjYXVzZSB0aGVyZSBhcmUgbm8gQVIgbGFncyBpbiB0aGUgbW9kZWwiKQogICAgcHJpbnQoa25pdHI6OmthYmxlKG9wdF9wbSksIGZvcm1hdCA9ICdwYW5kb2MnKQogICMgICBjYXQoIlxuIikKICB9CiAgIyBSZXR1cm4gdGhlIHh0cywgdGhlIHBsb3QsIHRoZSBsb3NzIGxpc3QsIGFuZCB0aGUgdGFibGVzCiAgcmV0dXJuKGxpc3QocGxvdF9tYXQpKQogICMgcmV0dXJuKGxpc3QocGxvdF9tYXQsIHBsb3QsIGxfbGlzdCwgdGFibGVzKSkKfQpgYGAKCmBgYHtyfQojJyBGdW5jdGlvbiB0byBwbG90IHRoZSBkYXRhIHdoaWNoIHdlIGdlbmVyYXRlIGluIHByZXZpb3VzIGZ1bmN0aW9ucwojJwojJyBAcGFyYW0gcGxvdF9tYXRyaXggLSBtYXRyaXggd2l0aCB0aGUgZGF0YSB0byBwbG90CiMnIEBwYXJhbSBub3JtX3ZhbHVlIC0gd2hhdCB0byBzdWJ0YWN0IGZyb20gdGhlIGRhdGEgdG8gbWFrZSBpdCBvbiBhIHBlcmNlbnRhZ2UgY2hhbmdlIGJhc2lzLiBEZWZhdWx0IGlzIDEwMC4KIycKIycgQHJldHVybiAKIycgQGV4cG9ydCAtIGEgcGxvdCBvZiB0aGUgZGF0YSBieSBkaWZmdXNpb24gaW5kZXggbnVtYmVyCiMnCiMnIEBleGFtcGxlcyA9IHBsdF9kYXRhKHBsb3RfbXR4W1sxXV0pLCBhYmMgPSBwbHRfZGF0YShwbG90X21hdCwgdGF1ID0gMC4wMSkKcGx0X2RhdGEgPSBmdW5jdGlvbihwbG90X21hdHJpeCwgdGF1LCByZXNwX3ZhciwgbnRlc3QpewogICMgRXN0YWJsaXNoIGEgbWF4aW11bSBhbmQgbWluaW11bSB2YWx1ZQogIG1heF92YWwgPSBtYXgocGxvdF9tYXRyaXhbLDE6bmNvbChwbG90X21hdHJpeCldKQogIG1pbl92YWwgPSBtaW4ocGxvdF9tYXRyaXhbLDE6bmNvbChwbG90X21hdHJpeCldKQogICMgQ2FsY3VsYXRlIGluaXRhbCBhbmQgZW5kaW5nIHRpbWUgdmFsdWUKICBzdGFydCA9IGluZGV4KHBsb3RfbWF0cml4KVsxXQogIGVuZCA9IGluZGV4KHBsb3RfbWF0cml4KVtucm93KHBsb3RfbWF0cml4KV0KICBpbmRfdmFscyA9IGluZGV4KHBsb3RfbWF0cml4KSAtIHN0YXJ0CiAgIyBDcmVhdGUgYW4gaW5pdGlhbCBwbG90IGFuZCBhZGQgbGluZXMKICAgIGZvciAoaSBpbiAxOm5jb2wocGxvdF9tYXRyaXgpKXsKICAgICAgaWYgKGkgPT0gMSl7CiAgICAgICAgIyA0LzIvMjAyMCAtIGZpeGluZyB0aGUgaW5kZXgKICAgICAgICBwbG90LnRzKGluZF92YWxzLHBsb3RfbWF0cml4WyxpXSwgdHlwZSA9ICJsIiwgeGxhYiA9IHBhc3RlKCJEYXlzIFNpbmNlIiwgYXMuRGF0ZShzdGFydCkpLCB5bGFiID0gIkFwcHJveC4gUGVyY2VudCBDaGFuZ2UgaW4gU1BZIiwgeWxpbSA9IGMobWluX3ZhbCxtYXhfdmFsKSwgbHdkID0gMSwgbWFpbiA9IHBhc3RlKCJQcmVkaWN0aW5nIiwgcmVzcF92YXIsICJSZXR1cm5zIGZyb20iLCBhcy5EYXRlKHN0YXJ0KSwgInRvIiwgYXMuRGF0ZShlbmQpKSwgc3ViID0gcGFzdGUoIlRoZSBWYVIgTGV2ZWwgaXMgIiwgMTAwKnRhdSwgIiUiLCAiOyBUaGVyZSBhcmUgIiwgbnRlc3QsICIgVHJhZGluZyBEYXlzIFBsb3R0ZWQgQWJvdmUiLCBzZXAgPSAiIikpCiAgICAgICAgIyBwbG90LnRzKGluZGV4KHBsb3RfbWF0cml4KSwgcGxvdF9tYXRyaXhbLGldLCB0eXBlID0gImwiLCB4bGFiID0gIlRyYWRpbmcgRGF5cyIsIHlsYWIgPSAiUGVyY2VudCBDaGFuZ2UgaW4gUEciLCB5bGltID0gYyhtaW5fdmFsLG1heF92YWwpLCBsd2QgPSAxLCBtYWluID0gIlByZWRpY3RpbmcgUEcgUmV0dXJucyBPdmVyIExhc3QgMjUwIFRyYWRpbmcgRGF5cyBpbiAyMDA4Iiwgc3ViID0gcGFzdGUoIlRoZSBWYVIgTGV2ZWwgaXMgIiwgMTAwKnRhdSwgIiUiLCBzZXAgPSAiIikpCiAgICB9IGVsc2UgaWYoaSAlaW4lIHNlcSgyLDgsMSkpIHsKICAgICAgICBsaW5lcyhpbmRfdmFscyxwbG90X21hdHJpeFssaV0sIGNvbCA9IGksIGx0eSA9IDIpCiAgICB9IGVsc2UgewogICAgICAgIGxpbmVzKGluZF92YWxzLHBsb3RfbWF0cml4WyxpXSwgY29sID0gaSwgbHR5ID0gMikKICAgIH0KICAgIH0KICAjIERlZmluZSBhIHNlcXVlbmNlIGZvciBwbG90dGluZwogIHBsb3Rfc2VxID0gc2VxKDEsIG5jb2wocGxvdF9tYXRyaXgpKQogICMgTW9kaWZ5aW5nIHRoZSBjb2RlIGJlbG93IHRvIGZpeCB0aGUgbGVnZW5kIG9uIDcuMzEuMjAyMAogIGxlZ2VuZCgidG9wbGVmdCIsIGxlZ2VuZCA9IGMoY29sbmFtZXMocGxvdF9tYXRyaXgpKSwgY29sID0gcGxvdF9zZXEsIGx0eSA9IGMoMSwgcmVwKDIsIG5jb2wocGxvdF9tYXRyaXgpLTEpKSwgbHdkID0gYygxLCByZXAoMSwgbmNvbChwbG90X21hdHJpeCktMSkpKQogICMgQWRkIGEgbGluZSBmb3IgMAogICMgYWJsaW5lKGggPSAwLCBjb2wgPSAiYmxhY2siLCBsdHkgPSAyKQp9CgoKYGBgCgpgYGB7cn0KIycgQSBmdW5jdGlvbiB0byBjYWxjdWxhdGUgbG9zc2VzIGJhc2VkIG9uIHRoZSB0ZXN0IHNhbXBsZQojJwojJyBAcGFyYW0gdHJ1ZV92ZWMgLSB0aGUgdHJ1ZSB2ZWN0b3Igb2YgcmV0dXJucwojJyBAcGFyYW0gcHJlZF92ZWMgLSB0aGUgcHJlZGljdGVkIHZlY3RvciBmcm9tIHRoZSBtb2RlbCBydW5zCiMnIEBwYXJhbSB0YXUgLSBWYVIgbGV2ZWwuIE11c3QgbWF0Y2ggd2hhdCB0aGUgbW9kZWwgdXNlZAojJwojJyBAcmV0dXJuIC0gdG90YWwgbG9zc2VzIGFuZCB0aGUgZW50aXJlIGxvc3MgdmVjdG9yCiMnIEBleHBvcnQKIycKIycgQGV4YW1wbGVzCmxvc3NfdGVzdCA9IGZ1bmN0aW9uKHRydWVfdmVjLCBwcmVkX3ZlYywgdGF1KXsKICAjIEluaXRpYWxpemUgYSBsb3NzIHZlY3RvcgogIGx2ZWMgPSByZXAoMCwgbGVuZ3RoKHRydWVfdmVjKSkKICAjIEluaXRpYWxpemUgYSBicmVhayB2ZWN0b3IgdG8gc2VlIHdoZW4gVmFSIGlzIGJyb2tlbgogIGJ2ZWMgPSByZXAoMCwgbGVuZ3RoKHRydWVfdmVjKSkKICBmb3IgKGkgaW4gMTpsZW5ndGgodHJ1ZV92ZWMpKXsKICAgICMgQ2FsY3VsYXRlIGFuIGluZGljYXRvciB2YXJpYWJsZQogICAgYnZlY1tpXSA9IGlmZWxzZSh0cnVlX3ZlY1tpXSA8IHByZWRfdmVjW2ldLCAxLDApCiAgICAjIFVzZSBpbmRpY2F0b3IgaW4gZnVuY3Rpb24gYmVsb3cKICAgIGx2ZWNbaV0gPSAodGF1IC0gYnZlY1tpXSkqKHRydWVfdmVjW2ldIC0gcHJlZF92ZWNbaV0pCiAgfQogICMgQWRkIHVwIHRoZSBsb3NzZXMKICAjIHN1bWxvc3MgPSBzdW0obHZlYykvbGVuZ3RoKGx2ZWMpCiAgc3VtbG9zcyA9IHN1bShsdmVjKQogICMgQWRkIHVwIHRoZSBWYVIgYnJlYWthZ2UKICB2YXJicmVhayA9IHN1bShidmVjKS9sZW5ndGgoYnZlYykKICByZXR1cm4obGlzdChzdW1sb3NzLGx2ZWMsIHZhcmJyZWFrLCBidmVjKSkKfQpgYGAKCgoKYGBge3J9CiMnIEEgZnVuY3Rpb24gdG8gY2FsY3VsYXRlIGxvc3NlcyBiYXNlZCBvbiB0aGUgcGxvdCBtYXRyaXgKIycKIycgQHBhcmFtIGRhdGFfbWF0IC0gYSBtYXRyaXggb2YgZm9yZWNhc3RlZCBWYVIgdmFsdWVzLCB3aXRoIHRoZSB0cnVlIHZhbHVlIGluIHRoZSBmaXJzdCBjb2x1bW4KIycgQHBhcmFtIHRhdSAtIFZhUiBsZXZlbC4gTXVzdCBtYXRjaCB3aGF0IHRoZSBtb2RlbCB1c2VkCiMnCiMnIEByZXR1cm4gLSBhIGxpc3Qgb2YgZm91ciBpdGVtcy4gCiMnIDEgPSBhIHZlY3RvciBvZiB0aGUgbG9zc2VzIG9mIGFsbCBtb2RlbHMuIAojJyAyID0gYSB2ZWN0b3Igc2hvd2luZyB0aGUgcGVyY2VudGFnZSBvZiBWYVIgYnJlYWtzIGJ5IG1vZGVsCiMnIDMgPSB0aGUgbG9zcyBtYXRyaXgKIycgNCA9IHRoZSBicmVhayBtYXRyaXgKIycgQGV4cG9ydAojJwojJyBAZXhhbXBsZXMKZ2VuX2xvc3NfdGVzdCA9IGZ1bmN0aW9uKGRhdGFfbWF0LCB0YXUpewogICMgSW5pdGlhbGl6ZSBsb3NzIGFuZCBicmVhayBtYXRyaWNlcwogIGxtYXQgPSBibWF0ID0gbWF0cml4KDAsIG5yb3cgPSBucm93KGRhdGFfbWF0KSwgbmNvbCA9IG5jb2woZGF0YV9tYXQpLTEpCiAgIyBidmVjID0gcmVwKDAsIGxlbmd0aCh0cnVlX3ZlYykpCiAgIyBQb3B1bGF0ZSB0aGUgbWF0cmljZXMKICBmb3IgKGkgaW4gMTpucm93KGxtYXQpKXsKICAgIGZvciAoaiBpbiAxOihuY29sKGxtYXQpKSl7CiAgICAgICMgQ2FsY3VsYXRlIGFuIGluZGljYXRvciB2YXJpYWJsZQogICAgICBibWF0W2ksal0gPSBpZmVsc2UoZGF0YV9tYXRbaSwxXSA8IGRhdGFfbWF0W2ksaisxXSwgMSwwKQogICAgICAjIFVzZSBpbmRpY2F0b3IgaW4gZnVuY3Rpb24gYmVsb3cKICAgICAgbG1hdFtpLGpdID0gKHRhdSAtIGJtYXRbaSxqXSkqKGRhdGFfbWF0W2ksMV0gLSBkYXRhX21hdFtpLGorMV0pCiAgICB9ICAgIAogIH0KICAjIEFkZCB1cCB0aGUgbG9zc2VzCiAgc3VtbG9zcyA9IGNvbFN1bXMobG1hdCkKICAjIEFkZCB1cCB0aGUgVmFSIGJyZWFrYWdlCiAgdmFyYnJlYWsgPSBjb2xTdW1zKGJtYXQpL25yb3coYm1hdCkKICByZXR1cm4obGlzdChzdW1sb3NzLCB2YXJicmVhaywgbG1hdCwgYm1hdCkpCn0KYGBgCgoKCmBgYHtyfQojJyBBIGZ1bmN0aW9uIHRvIG1ha2UgYSBuaWNlIGNvbXBhcmlzb24gb2YgbG9zc2VzCiMnCiMnIEBwYXJhbSBkYXRhX21hdCAtIGlucHV0IGRhdGEgbWF0cml4IHVzZWQgaW4gdGhlIGNhbGN1bGF0aW9uIG9mIGxvc3NlcwojJyBAcGFyYW0gbG9zc19saXN0IC0gYSBsaXN0IG9mIHRoZSBsb3NzZXMgY2FsY3VsYXRlZCBmcm9tIHRoZSBDQVZpYVIgZnVuY3Rpb24KIycgQHBhcmFtIHRhdSAtIHRoZSByaXNrIGxldmVsIHVzZWQKIycgQHBhcmFtIG50ZXN0IC0gdGhlIG51bWJlciBvZiB0ZXN0IHBvaW50cwojJwojJyBAcmV0dXJuCiMnIEBleHBvcnQgLSByZXR1cm5zIGEgbmljZWx5IGZvcm1hdHRlZCB0YWJsZQojJwojJyBAZXhhbXBsZXMgLSBwcmV0dHlfdGFibGVzKHBsb3RfbWF0LCBsX2xpc3QsIHRhdSA9IDAuMDEpCnByZXR0eV90YWJsZXMgPSBmdW5jdGlvbihkYXRhX21hdCwgbG9zc19saXN0LCB0YXUsIG50ZXN0KXsKICAjIENvbWJpbmUgaW50byBhIGRhdGEgZnJhbWUKICBkZiA9IGFzLmRhdGEuZnJhbWUocmJpbmQobG9zc19saXN0W1sxXV0sIGxvc3NfbGlzdFtbMl1dKSkKICAjIENhbGN1bGF0ZSBpbml0YWwgYW5kIGVuZGluZyB0aW1lIHZhbHVlCiAgc3RhcnQgPSBpbmRleChkYXRhX21hdClbMV0KICBlbmQgPSBpbmRleChkYXRhX21hdClbbnJvdyhkYXRhX21hdCldCiAgIyBBZGQgcm93L2NvbHVtbiBuYW1lcwogIGNvbG5hbWVzKGRmKSA8LSBjb2xuYW1lcyhkYXRhX21hdFssLTFdKQogIHJvd25hbWVzKGRmKSA8LSBjKCJMb3NzZXMiLCAiVmFSIEJyZWFrcyAoJSkiKQogICMgRWRpdHMgb24gNS4xMi4yMDIwIC0gZGl2aWRlIHRoZSB0YWJsZSBpbnRvIDIKICB1dl9kZiA9IGRmWywxOjRdCiAgbXZfZGYgPSBkZlssNTo4XQogICMgcHJpbnQodXZfZGYpCiAgIyBwcmludChtdl9kZikKICAjIENvbnZlcnQgdG8gdGFibGUKICBwcmludCh1dl9kZiAlPiUga2FibGUoY2FwdGlvbiA9IHBhc3RlKCJVbml2YXJpYXRlIENBVmlhUiBSZXN1bHRzIGZvciBhICIsIHRhdSoxMDAsICIlIFZhUiIsIHNlcCA9ICIiKSwgZGlnaXRzID0gMykgJT4lIGthYmxlX3N0eWxpbmcoInN0cmlwZWQiLCBmdWxsX3dpZHRoID0gRikgJT4lIGthYmxlX3N0eWxpbmcoKSAlPiUgZm9vdG5vdGUoZ2VuZXJhbCA9IHBhc3RlKCJDYWxjdWxhdGVkIHVzaW5nIiwgbnRlc3QsICJ0cmFkaW5nIGRheXMgZnJvbSIsIGFzLkRhdGUoc3RhcnQpLCAidG8iLCBhcy5EYXRlKGVuZCkpKSkKICBwcmludChtdl9kZiAlPiUga2FibGUoY2FwdGlvbiA9IHBhc3RlKCJNdWx0aXZhcmlhdGUgQ0FWaWFSIFJlc3VsdHMgZm9yIGEgIiwgdGF1KjEwMCwgIiUgVmFSIiwgc2VwID0gIiIpLCBkaWdpdHMgPSAzKSAlPiUga2FibGVfc3R5bGluZygic3RyaXBlZCIsIGZ1bGxfd2lkdGggPSBGKSAlPiUga2FibGVfc3R5bGluZygpICU+JSBmb290bm90ZShnZW5lcmFsID0gcGFzdGUoIkNhbGN1bGF0ZWQgdXNpbmciLCBudGVzdCwgInRyYWRpbmcgZGF5cyBmcm9tIiwgYXMuRGF0ZShzdGFydCksICJ0byIsIGFzLkRhdGUoZW5kKSkpKQogICMgQ29udmVydCB0byBhIHRhYmxlCiAgIyBkZiAlPiUga2FibGUoY2FwdGlvbiA9IHBhc3RlKCJDb21wYXJpc29uIG9mIFZhUiBNZXRob2RzIGZvciBhICIsIHRhdSoxMDAsICIlIFZhUiIsIHNlcCA9ICIiKSwgZGlnaXRzID0gMykgJT4lIGthYmxlX3N0eWxpbmcoInN0cmlwZWQiLCBmdWxsX3dpZHRoID0gRikgJT4lIGthYmxlX3N0eWxpbmcoKSAlPiUgZm9vdG5vdGUoZ2VuZXJhbCA9IHBhc3RlKCJDYWxjdWxhdGVkIHVzaW5nIiwgbnRlc3QsICJ0cmFkaW5nIGRheXMgZnJvbSIsIGFzLkRhdGUoc3RhcnQpLCAidG8iLCBhcy5EYXRlKGVuZCkpKQogICMgY2NfZGZbLSgxOjIpLF0gJT4lIGthYmxlKGNhcHRpb24gPSAiQWNjdXJhY3kgb2YgVmFSIEZvcmVjYXN0IGZvciBQRyBPdmVyIExhc3QgMjAwIFRyYWRpbmcgRGF5cyBpbiAyMDA4IiwgZGlnaXRzID0gMykgJT4lIGthYmxlX3N0eWxpbmcoZnVsbF93aWR0aCA9IEYpICU+JSBmb290bm90ZShnZW5lcmFsID0gIlRlc3RlZCBVc2luZyB0aGUgU3ltbWV0cmljIEFic29sdXRlIFZhbHVlIE1vZGVsIikKfQpgYGAKCiMgSGlkZGVuIE1hcmtvdiBNb2RlbCBXb3JrCgpCZWxvdyBpcyBhcmd1YWJseSB0aGUgbW9zdCBjb25zZXF1ZW50aWFsIHBsb3QgZnJvbSBteSBNLlMuIHRoZXNpcy4gVGhlIHJlYXNvbnMgZm9yIHRoaXMgYXJlIGJlY2F1c2UgaXQgZGVhbHMgd2l0aCBhbiBpbXBvcnRhbnQgVmFSIExldmVsIC0gMSUsIHdoaWNoIGluIHRoZSBjb250ZXh0IG9mIHRyYWRpbmcgZGF5cyBtZWFucyBhYm91dCB0aGUgd29yc3QgZGF5IG91dCBvZiAxMDAuIFRoZSBiaWdnZXN0IHRha2Vhd2F5IG1pZ2h0IGJlIHRoZSBmYWN0IHRoYXQgdGhlIGZvdXIgbGluZXMgZGFzaGVkIGxpbmVzIChjb3JyZXNwb25kaW5nIHRvIHRoZSBtdWx0aXZhcmlhdGUgQ0FWaWFSIG1vZGVsKSBkbyBub3QgcGVyZm9ybSBhcyB3ZWxsIGFzIHRoZSBsYXN0IGZvdXIgbGluZXMsIHdoaWNoIHJlZmVyIHRvIHRoZSB1bml2YXJpYXRlIG1vZGVsLiBUaGlzIGNhbiBhbHNvIGJlIHNlZW4gaW4gdGhlIHRhYmxlIG9mIGxvc3NlcyBwcmludGVkIGJlbG93LgoKIyMgTm90YXRpb24KCkJlbG93IGlzIHRoZSBub3RhdGlvbiB1c2VkIGxhdGVyIGluIHRoaXMgcGFwZXIuIEl0ZW1zIDIgLSA1IGxpc3RlZCBiZWxvdyBhcmUgbmV3IG11bHRpdmFyaWF0ZSBDQVZpYVIgbW9kZWxzIGRldmVsb3BlZCBpbiB0aGlzIHRoZXNpczsgbW9kZWxzIDYgLSA5IGFyZSBmcm9tIHRoZSBlc3RhYmxpc2hlZCB1bml2YXJpYXRlIENBVmlhUiBtb2RlbCBkZXZlbG9wZWQgYnkgRW5nbGUgYW5kIE1hbmdhbmVsbGkuCgoxLiBTUFk6IFNQWSBFVEYKMi4gTm8gQVI6IE11bHRpdmFyaWF0ZSBDQVZpYVIgTW9kZWwgd2l0aCBubyBsYWdzCjMuIEFSOiBNdWx0aXZhcmlhdGUgQ0FWaWFSIE1vZGVsIHdpdGggJHAkIGxhZ3MKNC4gU0FWIEFSOiBNdWx0aXZhcmlhdGUgQ0FWaWFSIE1vZGVsIHdpdGggJHAkIGFic29sdXRlIHZhbHVlIGxhZ3MKNS4gQVMgQVI6IE11bHRpdmFyaWF0ZSBDQVZpYVIgTW9kZWwgd2l0aCAkMnAkIGxhZ3Mgd2l0aCBhc3ltbWV0cmljIHNsb3Blcwo2LiBTQVY6IFVuaXZhcmlhdGUgQ0FWaWFSIE1vZGVsIHdpdGggc3ltbWV0cmljIGFic29sdXRlIGZyYW1ld29yawo3LiBBc3ltLiBTbG9wZTogVW5pdmFyaWF0ZSBDQVZpYVIgTW9kZWwgd2l0aCBhc3ltbWV0cmljIHNsb3BlIGZyYW1ld29yawo4LiBJbmQuIEdBUkNIOiBVbml2YXJpYXRlIENBVmlhUiBNb2RlbCB3aXRoIGluZGlyZWN0IEdBUkNIIGZyYW1ld29yawo5LiBBZGFwdGl2ZTogVW5pdmFyaWF0ZSBDQVZpYVIgTW9kZWwgd2l0aCBhZGFwdGl2ZSAgc2xvcGUgZnJhbWV3b3JrCgpgYGB7ciwgcmVzdWx0cz0gICdhc2lzJ30KIyBDYWxsIHRoZSBhYm92ZSBmdW5jdGlvbiB0byBpbXBvcnQgZGF0YSBmcm9tIG15IHRoZXNpcwp2MV8yMDA4X2FsbGV0ZiA9IHZhcl9pbnB1dF9kaXNwKCIvVXNlcnMvc3RldmVubW9lbi9Eb2N1bWVudHMvR2l0SHViL0NBVmlhUl9NU190aGVzaXMvRGF0YV9FeHBvcnQvU1BZX2FsbF9FVEZfcnVucy8iLCJ2YXJfMXBjXzIwMDhfYWxsX2V0Zi5jc3YiLCAwLjAxLCBwcmludF9ncmFwaCA9IDEsIHByaW50X212X3RhYmxlID0gMCwgcHJpbnRfdXZfdGFibGUgPSAwLCBwcmludF9vcHRfcGFyYW0gPTApCgoKYGBgCgoKYGBge3J9CiMgVGhlc2UgYXJlIHRoZSBsb3NzZXMgZ2VuZXJhdGVkIGZyb20gb3VyIGZpbmFsIHJ1bgp0ZXN0X2xvc3MgPSBnZW5fbG9zc190ZXN0KGRhdGFfbWF0ID0gdjFfMjAwOF9hbGxldGZbWzFdXSwgdGF1ID0gMC4wMSlbWzNdXQoKCmBgYAoKYGBge3J9CiMgTGV0J3Mgc2VlIHRoZSB2YWx1ZXMgb2YgdGhlIGxvc3Nlcwp0b3RhbF9sb3NzX2RmID0gYXMuZGF0YS5mcmFtZSh0KGNvbFN1bXModGVzdF9sb3NzKSkpCnJvd25hbWVzKHRvdGFsX2xvc3NfZGYpIDwtIGMoIkxvc3NlcyBieSBNb2RlbCIpCmNvbG5hbWVzKHRvdGFsX2xvc3NfZGYpIDwtIGNvbG5hbWVzKHYxXzIwMDhfYWxsZXRmW1sxXV0pWy0xXQoKIyBTdWJzZXQgdGhlIGRhdGEgZnJhbWVzCmZpcnN0XzQgPC0gdG90YWxfbG9zc19kZlsxLDE6NF0KbGFzdF80IDwtIHRvdGFsX2xvc3NfZGZbMSw1OjhdCgojIFByaW50IHRoZXNlIG91dApmaXJzdF80ICU+JSBrYWJsZShjYXB0aW9uID0gIkxvc3NlcyBPdmVyIHRoZSBMYXN0IDI1MCBUcmFkaW5nIERheXMgaW4gMjAwOCBmb3IgdGhlIE11bHRpdmFyaWF0ZSBDQVZpYVIgTW9kZWxzIiwgZGlnaXRzID0gMykgJT4lIGthYmxlX3N0eWxpbmcoInN0cmlwZWQiLCBmdWxsX3dpZHRoID0gRikgJT4lIGthYmxlX3N0eWxpbmcoKSAKbGFzdF80ICU+JSBrYWJsZShjYXB0aW9uID0gIkxvc3NlcyBPdmVyIHRoZSBMYXN0IDI1MCBUcmFkaW5nIERheXMgaW4gMjAwOCBmb3IgdGhlIFVuaXZhcmlhdGUgQ0FWaWFSIE1vZGVscyIsIGRpZ2l0cyA9IDMpICU+JSBrYWJsZV9zdHlsaW5nKCJzdHJpcGVkIiwgZnVsbF93aWR0aCA9IEYpICU+JSBrYWJsZV9zdHlsaW5nKCkgCmBgYAoKQmFzZWQgb24gdGhlIGxvc3NlcyBmb3IgZWFjaCBtb2RlbCBkdXJpbmcgdGhlIGxhc3QgMjUwIHRyYWRpbmcgZGF5cyBpbiAyMDA4LCBpdCBsb29rcyBsaWtlIHRoZSBiZXN0IG9wdGlvbnMgYXJlIHRoZSBtdWx0aXZhcmlhdGUgQ0FWaWFSIG1vZGVsIHdpdGhvdXQgQVIgdGVybXMgZm9yIHRoZSBtdWx0aXZhcmlhdGUgbW9kZWwgY2xhc3MgYW5kIHRoZSBzeW1tZXRyaWMgYWJzb2x1dGUgdmFsdWUgbW9kZWwgZm9yIHRoZSB1bml2YXJpYXRlIG1vZGVsIGNsYXNzLiBUaGUgZnVsbCBtb2RlbCBzcGVjaWZpY2F0aW9ucyBjYW4gYmUgZm91bmQgaW4gdGhlIGFwcGVuZGl4LgoKQ29pbmNpZGVudGFsbHksIHRoZXNlIGFyZSBhbW9uZyB0aGUgc2ltcGxlc3QgbW9kZWxzIGF2YWlsYWJsZSBhbW9uZyB0aGUgbW9kZWxzIHBsb3R0ZWQgYWJvdmUuIEEgbmF0dXJhbCBjcml0aWNpc20gb2YgdGhpcyBhcHByb2FjaCBpcyB0aGF0IHRoZSBsb3NzZXMgYXJlIGxvd2VyIGZvciB0aGUgQ0FWaWFSIHNwZWNpZmljYXRpb25zIHdpdGhvdXQgbGFnZ2VkIHByZWRpY3RvcnMuIFRoaXMgaXMgYSBmYWlyIHBvaW50LCBob3dldmVyLCB0aGUgcGVyaW9kIG9mIDIwMDggaXMgYSBwZXJpb2Qgb2YgZXh0cmVtZSBjcmlzaXMsIGFuZCBhIHNpbXBsZXIsIEFSTUEtc3R5bGUgbW9kZWwgbWlnaHQgc2VlbSB0byB3b3JrIGJldHRlciBvdGhlciB0aGluZ3MgZXF1YWwuIEZ1dHVyZSB3b3JrIGNhbiBleHRlbmQgdGhpcyB3b3JrIHRvIG90aGVyIHBlcmlvZHMuIFNpbmNlIHRoZXNlIGFyZSB0aGUgYmVzdCB0d28gb3B0aW9ucyBkdXJpbmcgdGhpcyBwZXJpb2Qgb2YgaW50ZXJlc3QsIHRoZSBuZXh0IHN0ZXAgaXMgdG8gZmluZCByZWFzb25hYmxlIHBhcmFtZXRyaWMgZGlzdHJpYnV0aW9ucyB0byBtb2RlbCB0aGVpciB2YWx1ZXMuCgojIyBGaW5kaW5nIERpc3RyaWJ1dGlvbnMgb2YgdGhlIEZvcmVjYXN0cwoKVG8gZml0IHRoZSBIaWRkZW4gTWFya292IE1vZGVsLCBpdCBpcyBuZWNlc3NhcnkgdG8gZmluZCBkaXN0cmlidXRpb25zIHRoYXQgYXBwcm9wcmlhdGVseSBmaXQgdGhlIHR3byBtb2RlbHMgYWJvdmUuIFdoaWxlIHRoZSBkaXN0cmlidXRpb24gb2YgcHJlZGljdGlvbnMgZnJvbSB0aGUgbXVsdGl2YXJpYXRlIG1vZGVsIGlzIGZhaXJseSB3ZWxsLWFwcHJveGltYXRlZCBieSBhIG5vcm1hbCBkaXN0cmlidXRpb24sIHRoZSBkaXN0cmlidXRpb24gb2YgcHJlZGljdGlvbnMgZnJvbSB0aGUgdW5pdmFyaWF0ZSBtb2RlbCB3YXMgaGlnaGx5IGxlZnQtc2tld2VkLCB3aGljaCBtYWtlcyBmaXR0aW5nIGEgZGlzdHJpYnV0aW9uIGRpZmZpY3VsdC4KClRoZSBmaXJzdCBzdGVwIHdhcyB0byB0cnkgdHJhbnNmb3JtYXRpb25zIG9mIHRoZSBhZm9yZW1lbnRpb25lZCBwcmVkaWN0aW9ucyBmcm9tIHRoZSB1bml2YXJpYXRlIG1vZGVsLCBuYW1lbHkgJFxzcXJ0e1xtYXgoeCsxKSAteH0kLCAkXGxvZ197MTB9IChcbWF4KHgrMSkgLXgpJCwgYW5kICQxLyhcbWF4KHgrMSkgLXgpJCBmb2xsb3dpbmcgdGhlIHN1Z2dlc3Rpb25zIGZvdW5kIGhlcmUgW0BLYXNzYW1iYXJhXS4gV2hpbGUgdGhlc2UgZGlkIChpbiBzb21lIGNhc2VzKSBlbGltaW5hdGUgdGhlIGxlZnQtc2tldywgaXQgb2Z0ZW4gY3JlYXRlZCBhIG1vcmUgcHJvbm91bmNlZCByaWdodC1za2V3ISBUaHVzLCBJIGF0dGVtcHRlZCB0byBtb2RlbCB0aGUgZGF0YSB3aXRob3V0IHRyYW5zZm9ybWF0aW9uLgoKVGhlcmUgYXJlIG1hbnkgY2FuZGlkYXRlIGRpc3RyaWJ1dGlvbnMgdGhhdCBjb3VsZCBiZSB1c2VkIHRvIG1vZGVsIHRoZSBlbXBpcmljYWwgZGlzdHJpYnV0aW9uIG9mIHZhbHVlcyBmcm9tIHRoZSB1bml2YXJpYXRlIENBVmlhUiBtb2RlbCwgYnV0IHRoZSB0aHJlZSB0aGF0IHN0b29kIG91dCBhcmU6CgoxLiBUaGUgU2tldyBOb3JtYWwgRGlzdHJpYnV0aW9uIChwYXJhbWV0ZXJpemVkIGJ5IGxvY2F0aW9uLCBzY2FsZSwgYW5kIHNoYXBlIHBhcmFtZXRlcnMpCjIuIFRoZSBHdW1iZWwgRGlzdHJpYnV0aW9uIChwYXJhbWV0ZXJpemVkIGJ5IGxvY2F0aW9uIGFuZCBzY2FsZSBwYXJhbWV0ZXJzKQozLiBUaGUgR2VuZXJhbGl6ZWQgRXh0cmVtZSBWYWx1ZSBEaXN0cmlidXRpb24gKHBhcmFtZXRlcml6ZWQgYnkgbG9jYXRpb24sIHNjYWxlLCBhbmQgc2hhcGUgcGFyYW1ldGVycykKCgoKYGBge3J9CiMgRXh0cmFjdCB0aGUgZGF0YQpzbWFsbF9kZiA9IHYxXzIwMDhfYWxsZXRmW1sxXV1bLGMoMSwyLDYpXQoKIyBBZGQgMQojIHNtYWxsX2RmMiA9IHNtYWxsX2RmICsgMQoKIyBUaGVzZSBmaXRzIGRvbid0IHdvcmsgdmVyeSB3ZWxsCiMgaGlzdChsb2coc21hbGxfZGYyWywyXSksIGJyZWFrcyA9IDI1KQojIGhpc3Qoc21hbGxfZGYyWywzXSwgYnJlYWtzID0gMjUpCiMgaGlzdChsb2coc21hbGxfZGYyWywzXSksIGJyZWFrcyA9IDI1KQojIGhpc3QoKHNtYWxsX2RmWywzXSksIGJyZWFrcyA9IDI1KQoKIyBzbWFsbF9kZjIKIyA/c25vcm1GaXQKCiMgTGV0J3MgdHJ5IGFub3RoZXIgdHJhbnNmb3JtYXRpb24KIyB0MSA9IHNxcnQobWF4KHNtYWxsX2RmWywzXSsxKSAtIHNtYWxsX2RmWywzXSkKIyB0MiA9IGxvZzEwKG1heChzbWFsbF9kZlssM10rMSkgLSBzbWFsbF9kZlssM10pCiMgdDMgPSAxLyhtYXgoc21hbGxfZGZbLDNdKzEpIC0gc21hbGxfZGZbLDNdKQoKIyBQbG90IHRoZSB0cmFuc2Zvcm1hdGlvbnMKIyBoaXN0KHQxLCBicmVha3MgPSAyNSkKIyBoaXN0KHQyLCBicmVha3MgPSAyNSkKIyBoaXN0KHQzLCBicmVha3MgPSAyNSkKCgpgYGAKCgpgYGB7cn0KIyBGaXQgYSBza2V3IG5vcm1hbAptMSA9IHNub3JtRml0KHNtYWxsX2RmWywyXSkKbTIgPSBzbm9ybUZpdChzbWFsbF9kZlssM10pCgojIG0xCgojIHNub3JtRml0KHNtYWxsX2RmWywyXSsxKQojIHNub3JtRml0KHNtYWxsX2RmWywzXSsxKQojIFRoZXNlIG1heSBub3Qgd29yayB2ZXJ5IHdlbGwKCiMgc3F1YXJlX3ZhbCA9IHNtYWxsX2RmWywzXV4yCiMgbTMgPSBzbm9ybUZpdChzcXVhcmVfdmFsKQojIG00ID0gc25vcm1GaXQodDMpCiMgbTQKCgoKIyBoaXN0KChzbWFsbF9kZlssM10pXjIsIGJyZWFrcyA9IDI1KQpgYGAKCgpgYGB7cn0KIyBGaXQgYSBndW1iZWwgZnVuY3Rpb24KZ3VtX3BhcmFtID0gZ3VtLmZpdChzbWFsbF9kZlssM10sIHNob3cgPSBGQUxTRSkKIyA/Z3VtLmZpdAojIGd1bV9wYXJhbSRtbGUKCiMgVHJ5IGZpdHRpbmcgYSBHRVYgZGlzdHJpYnV0aW9uCmdldl9wYXJhbSA9IGdldi5maXQoc21hbGxfZGZbLDNdLCBzaG93ID0gRkFMU0UpCiMgZ2V2X3BhcmFtJG1sZQoKIyAjIFBsb3QgaGlzdG9ncmFtcwojICMgR3VtYmVsCiMgaCA9IGhpc3Qoc21hbGxfZGZbLDNdLCBicmVha3MgPSAyNSkKIyAjIE92ZXJzZXQgYSBkZW5zaXR5IGZ1bmN0aW9uCiMgeGZpdDwtc2VxKG1pbihzbWFsbF9kZlssM10pLG1heChzbWFsbF9kZlssM10pLGxlbmd0aD0yNTApCiMgeWZpdCA9IGRndW1iZWwoeGZpdCwgbG9jID0gZ3VtX3BhcmFtJG1sZVsxXSwgc2NhbGUgPSBndW1fcGFyYW0kbWxlWzJdKQojIHlmaXQgPC0geWZpdCpkaWZmKGgkbWlkc1sxOjJdKSpsZW5ndGgoc21hbGxfZGZbLDNdKQojIGxpbmVzKHhmaXQsIHlmaXQsIGNvbD0iYmx1ZSIsIGx3ZD0yKQojIAojICMgR0VWCiMgaCA9IGhpc3Qoc21hbGxfZGZbLDNdLCBicmVha3MgPSAyNSkKIyAjIE92ZXJzZXQgYSBkZW5zaXR5IGZ1bmN0aW9uCiMgeGZpdDwtc2VxKG1pbihzbWFsbF9kZlssM10pLG1heChzbWFsbF9kZlssM10pLGxlbmd0aD0yNTApCiMgeWZpdCA9IGRnZXYoeGZpdCwgbG9jID0gZ2V2X3BhcmFtJG1sZVsxXSwgc2NhbGUgPSBnZXZfcGFyYW0kbWxlWzJdLCBzaGFwZSA9IGdldl9wYXJhbSRtbGVbM10pCiMgeWZpdCA8LSB5Zml0KmRpZmYoaCRtaWRzWzE6Ml0pKmxlbmd0aChzbWFsbF9kZlssM10pCiMgbGluZXMoeGZpdCwgeWZpdCwgY29sPSJibHVlIiwgbHdkPTIpCgpwYXIobWZyb3cgPSBjKDEsMikpCgojIExldCdzIGxvb2sgYXQgdGhlIGRhdGEKaCA9IGhpc3Qoc21hbGxfZGZbLDJdLCBicmVha3MgPSAyNSwgeGxhYiA9ICJNb2RlbGVkIFZhbHVlcyIsIG1haW4gPSAiTXVsdGl2YXJpYXRlIENBVmlhUiIpCiMgT3ZlcnNldCBhIGRlbnNpdHkgZnVuY3Rpb24KeGZpdDwtc2VxKG1pbihzbWFsbF9kZlssMl0pLG1heChzbWFsbF9kZlssMl0pLGxlbmd0aD0yNTApCnlmaXQgPSBkc25vcm0oeGZpdCwgbWVhbiA9IG0xJHBhclsxXSwgc2QgPSBtMSRwYXJbMl0sIHhpID0gbTEkcGFyWzNdKQp5Zml0IDwtIHlmaXQqZGlmZihoJG1pZHNbMToyXSkqbGVuZ3RoKHNtYWxsX2RmWywyXSkKbGluZXMoeGZpdCwgeWZpdCwgY29sPSJibHVlIiwgbHdkPTIpCiMgT3ZlcnNldCBhIG5vcm1hbCBkZW5zaXR5IGZ1bmN0aW9uCnhmaXQ8LXNlcShtaW4oc21hbGxfZGZbLDJdKSxtYXgoc21hbGxfZGZbLDJdKSxsZW5ndGg9MjUwKQp5Zml0X24gPSBkbm9ybSh4Zml0LCBtZWFuID0gbWVhbihzbWFsbF9kZlssMl0pLCBzZCA9IHNkKHNtYWxsX2RmWywyXSkpCnlmaXRfbiA8LSB5Zml0X24qZGlmZihoJG1pZHNbMToyXSkqbGVuZ3RoKHNtYWxsX2RmWywyXSkKbGluZXMoeGZpdCwgeWZpdF9uLCBjb2w9InJlZCIsIGx3ZD0yLCBsdHkgPSAyKQoKIyBBZGQgYSBsZWdlbmQKbGVnZW5kKCJ0b3BsZWZ0IiwgbGVnZW5kID0gYygiTm9ybWFsIiwgIlNrZXcgTm9ybWFsIiksIGNvbCA9IGMoImJsdWUiLCAicmVkIiksIGx0eSA9IGMoMSwyKSwgbHdkID0gYygyLDIpKQoKCgojIExldCdzIGxvb2sgYXQgdGhlIHNlY29uZCBzZXQgb2YgZGF0YQpoID0gaGlzdChzbWFsbF9kZlssM10sIGJyZWFrcyA9IDI1LCB4bGFiID0gIk1vZGVsZWQgVmFsdWVzIiwgbWFpbiA9ICJVbml2YXJpYXRlIENBVmlhUiIpCiMgT3ZlcnNldCBhIGRlbnNpdHkgZnVuY3Rpb24gLSBTa2V3IE5vcm1hbAp4Zml0PC1zZXEobWluKHNtYWxsX2RmWywzXSksbWF4KHNtYWxsX2RmWywzXSksbGVuZ3RoPTI1MCkKeWZpdCA9IGRzbm9ybSh4Zml0LCBtZWFuID0gbTIkcGFyWzFdLCBzZCA9IG0yJHBhclsyXSwgeGkgPSBtMiRwYXJbM10pCnlmaXQgPC0geWZpdCpkaWZmKGgkbWlkc1sxOjJdKSpsZW5ndGgoc21hbGxfZGZbLDNdKQpsaW5lcyh4Zml0LCB5Zml0LCBjb2w9ImJsdWUiLCBsd2Q9MikKIyBPdmVyc2V0IGEgZGVuc2l0eSBmdW5jdGlvbiAtIEd1bWJlbAp4Zml0PC1zZXEobWluKHNtYWxsX2RmWywzXSksbWF4KHNtYWxsX2RmWywzXSksbGVuZ3RoPTI1MCkKeWZpdCA9IGRndW1iZWwoeGZpdCwgbG9jID0gZ3VtX3BhcmFtJG1sZVsxXSwgc2NhbGUgPSBndW1fcGFyYW0kbWxlWzJdKQp5Zml0IDwtIHlmaXQqZGlmZihoJG1pZHNbMToyXSkqbGVuZ3RoKHNtYWxsX2RmWywzXSkKbGluZXMoeGZpdCwgeWZpdCwgY29sPSJyZWQiLCBsd2Q9MikKIyBPdmVyc2V0IGEgZGVuc2l0eSBmdW5jdGlvbiAtIEdFVgp4Zml0PC1zZXEobWluKHNtYWxsX2RmWywzXSksbWF4KHNtYWxsX2RmWywzXSksbGVuZ3RoPTI1MCkKeWZpdCA9IGRnZXYoeGZpdCwgbG9jID0gZ2V2X3BhcmFtJG1sZVsxXSwgc2NhbGUgPSBnZXZfcGFyYW0kbWxlWzJdLCBzaGFwZSA9IGdldl9wYXJhbSRtbGVbM10pCnlmaXQgPC0geWZpdCpkaWZmKGgkbWlkc1sxOjJdKSpsZW5ndGgoc21hbGxfZGZbLDNdKQpsaW5lcyh4Zml0LCB5Zml0LCBjb2w9ImdyZWVuIiwgbHdkPTIpCgojIEFkZCBhIGxlZ2VuZApsZWdlbmQoInRvcGxlZnQiLCBsZWdlbmQgPSBjKCJTa2V3IE5vcm1hbCIsICJHdW1iZWwiLCAiR0VWIiksIGNvbCA9IGMoImJsdWUiLCAicmVkIiwgImdyZWVuIiksIGx0eSA9IGMoMSwxLDEpLCBsd2QgPSBjKDIsMiwyKSkKCiMgcGFyKG1mcm93ID0gYygxLDMpKQojIAojICMgTGV0J3MgbG9vayBhdCB0aGUgZGF0YQojIGggPSBoaXN0KHNtYWxsX2RmWywyXSwgYnJlYWtzID0gMjUpCiMgIyBPdmVyc2V0IGEgZGVuc2l0eSBmdW5jdGlvbgojIHhmaXQ8LXNlcShtaW4oc21hbGxfZGZbLDJdKSxtYXgoc21hbGxfZGZbLDJdKSxsZW5ndGg9MjUwKQojIHlmaXQgPSBkc25vcm0oeGZpdCwgbWVhbiA9IG0xJHBhclsxXSwgc2QgPSBtMSRwYXJbMl0sIHhpID0gbTEkcGFyWzNdKQojIHlmaXQgPC0geWZpdCpkaWZmKGgkbWlkc1sxOjJdKSpsZW5ndGgoc21hbGxfZGZbLDJdKQojIGxpbmVzKHhmaXQsIHlmaXQsIGNvbD0iYmx1ZSIsIGx3ZD0yKQojICMgT3ZlcnNldCBhIG5vcm1hbCBkZW5zaXR5IGZ1bmN0aW9uCiMgeGZpdDwtc2VxKG1pbihzbWFsbF9kZlssMl0pLG1heChzbWFsbF9kZlssMl0pLGxlbmd0aD0yNTApCiMgeWZpdF9uID0gZG5vcm0oeGZpdCwgbWVhbiA9IG1lYW4oc21hbGxfZGZbLDJdKSwgc2QgPSBzZChzbWFsbF9kZlssMl0pKQojIHlmaXRfbiA8LSB5Zml0X24qZGlmZihoJG1pZHNbMToyXSkqbGVuZ3RoKHNtYWxsX2RmWywyXSkKIyBsaW5lcyh4Zml0LCB5Zml0X24sIGNvbD0icmVkIiwgbHdkPTIsIGx0eSA9IDIpCiMgCiMgIyBMZXQncyBsb29rIGF0IHRoZSBzZWNvbmQgc2V0IG9mIGRhdGEKIyBoID0gaGlzdChzbWFsbF9kZlssM10sIGJyZWFrcyA9IDI1KQojICMgT3ZlcnNldCBhIGRlbnNpdHkgZnVuY3Rpb24KIyB4Zml0PC1zZXEobWluKHNtYWxsX2RmWywzXSksbWF4KHNtYWxsX2RmWywzXSksbGVuZ3RoPTI1MCkKIyB5Zml0ID0gZHNub3JtKHhmaXQsIG1lYW4gPSBtMiRwYXJbMV0sIHNkID0gbTIkcGFyWzJdLCB4aSA9IG0yJHBhclszXSkKIyB5Zml0IDwtIHlmaXQqZGlmZihoJG1pZHNbMToyXSkqbGVuZ3RoKHNtYWxsX2RmWywzXSkKIyBsaW5lcyh4Zml0LCB5Zml0LCBjb2w9ImJsdWUiLCBsd2Q9MikKIyAKIyAjICMgTGV0J3MgbG9vayBhdCB0aGUgc2Vjb25kIHNldCBvZiBkYXRhCiMgIyBoID0gaGlzdChzcXVhcmVfdmFsLCBicmVha3MgPSAyNSkKIyAjICMgT3ZlcnNldCBhIGRlbnNpdHkgZnVuY3Rpb24KIyAjIHhmaXQ8LXNlcShtaW4oc3F1YXJlX3ZhbCksbWF4KHNxdWFyZV92YWwpLGxlbmd0aD0yNTApCiMgIyB5Zml0ID0gZHNub3JtKHhmaXQsIG1lYW4gPSBtMyRwYXJbMV0sIHNkID0gbTMkcGFyWzJdLCB4aSA9IG0zJHBhclszXSkKIyAjIHlmaXQgPC0geWZpdCpkaWZmKGgkbWlkc1sxOjJdKSpsZW5ndGgoc3F1YXJlX3ZhbCkKIyAjIGxpbmVzKHhmaXQsIHlmaXQsIGNvbD0iYmx1ZSIsIGx3ZD0yKQojIAojICMgTGV0J3MgbG9vayBhdCB0aGUgc2Vjb25kIHNldCBvZiBkYXRhCiMgaCA9IGhpc3QodDMsIGJyZWFrcyA9IDI1KQojICMgT3ZlcnNldCBhIGRlbnNpdHkgZnVuY3Rpb24KIyB4Zml0PC1zZXEobWluKHQzKSxtYXgodDMpLGxlbmd0aD0yNTApCiMgeWZpdCA9IGRzbm9ybSh4Zml0LCBtZWFuID0gbTQkcGFyWzFdLCBzZCA9IG00JHBhclsyXSwgeGkgPSBtNCRwYXJbM10pCiMgeWZpdCA8LSB5Zml0KmRpZmYoaCRtaWRzWzE6Ml0pKmxlbmd0aCh0MykKIyBsaW5lcyh4Zml0LCB5Zml0LCBjb2w9ImJsdWUiLCBsd2Q9MikKCmBgYAoKCgpgYGB7cn0KIyAjIEZpdCBhIGd1bWJlbCBmdW5jdGlvbgojIGd1bV9wYXJhbSA9IGd1bS5maXQoc21hbGxfZGZbLDNdKQojIGd1bV9wYXJhbSRtbGUKIyAKIyAjIFRyeSBmaXR0aW5nIGEgR0VWIGRpc3RyaWJ1dGlvbgojIGdldl9wYXJhbSA9IGdldi5maXQoc21hbGxfZGZbLDNdKQojIGdldl9wYXJhbSRtbGUKIyAKIyAjIFBsb3QgaGlzdG9ncmFtcwojICMgR3VtYmVsCiMgaCA9IGhpc3Qoc21hbGxfZGZbLDNdLCBicmVha3MgPSAyNSkKIyAjIE92ZXJzZXQgYSBkZW5zaXR5IGZ1bmN0aW9uCiMgeGZpdDwtc2VxKG1pbihzbWFsbF9kZlssM10pLG1heChzbWFsbF9kZlssM10pLGxlbmd0aD0yNTApCiMgeWZpdCA9IGRndW1iZWwoeGZpdCwgbG9jID0gZ3VtX3BhcmFtJG1sZVsxXSwgc2NhbGUgPSBndW1fcGFyYW0kbWxlWzJdKQojIHlmaXQgPC0geWZpdCpkaWZmKGgkbWlkc1sxOjJdKSpsZW5ndGgoc21hbGxfZGZbLDNdKQojIGxpbmVzKHhmaXQsIHlmaXQsIGNvbD0iYmx1ZSIsIGx3ZD0yKQojIAojICMgR0VWCiMgaCA9IGhpc3Qoc21hbGxfZGZbLDNdLCBicmVha3MgPSAyNSkKIyAjIE92ZXJzZXQgYSBkZW5zaXR5IGZ1bmN0aW9uCiMgeGZpdDwtc2VxKG1pbihzbWFsbF9kZlssM10pLG1heChzbWFsbF9kZlssM10pLGxlbmd0aD0yNTApCiMgeWZpdCA9IGRnZXYoeGZpdCwgbG9jID0gZ2V2X3BhcmFtJG1sZVsxXSwgc2NhbGUgPSBnZXZfcGFyYW0kbWxlWzJdLCBzaGFwZSA9IGdldl9wYXJhbSRtbGVbM10pCiMgeWZpdCA8LSB5Zml0KmRpZmYoaCRtaWRzWzE6Ml0pKmxlbmd0aChzbWFsbF9kZlssM10pCiMgbGluZXMoeGZpdCwgeWZpdCwgY29sPSJibHVlIiwgbHdkPTIpCgpgYGAKClRvIGZpdCB0aGUgYWJvdmUgaGlzdG9ncmFtcyx0aGUgb3B0aW1hbCBwYXJhbWV0ZXJzIHdlcmUgZml0IHVzaW5nIG1heGltdW0gbGlrZWxpaG9vZC4gTm90ZSB0aGF0IHdoaWxlIHRoZXJlIHdlcmUgY29udmVyZ2VuY2UgaXNzdWVzIHVzZWQgaW4gZml0dGluZyB0aGUgc2tldy1ub3JtYWwgZGlzdHJpYnV0aW9uLCB0aGVyZSB3ZXJlIG5vdCBpc3N1ZXMgd2l0aCBmaXR0aW5nIHRoZSBHdW1iZWwgb3IgdGhlIEdFViBkaXN0cmlidXRpb25zLgoKYGBge3J9CiMgQmVsb3cgYXJlIHRoZSBvcHRpbWFsIHBhcmFtZXRlcnMgZm9yIHRoZSBzZWNvbmQgbW9kZWwKbm9ybV9wYXJhbV9kZiA9IGFzLmRhdGEuZnJhbWUoY2JpbmQobWVhbihzbWFsbF9kZlssMl0pLHNkKHNtYWxsX2RmWywyXSkpKQpyb3duYW1lcyhub3JtX3BhcmFtX2RmKSA8LSBjKCJPcHRpbWFsIFBhcmFtZXRlcnMiKQpjb2xuYW1lcyhub3JtX3BhcmFtX2RmKSA8LSBjKCJNZWFuIiwgIlN0YW5kYXJkIERldmlhdGlvbiIpCgojIERpc3BsYXkgYSBwcmV0dHkgdGFibGUKbm9ybV9wYXJhbV9kZiAlPiUga2FibGUoY2FwdGlvbiA9ICJPcHRpbWFsIFBhcmFtZXRlcnMgZm9yIHRoZSBOb3JtYWwgRGlzdHJpYnV0aW9uIiwgZGlnaXRzID0gMikgJT4lIGthYmxlX3N0eWxpbmcoInN0cmlwZWQiLCBmdWxsX3dpZHRoID0gRikgJT4lIGthYmxlX3N0eWxpbmcoKSAlPiUgZm9vdG5vdGUoZ2VuZXJhbCA9ICJUaGUgTWVhbiBXYXMgRXN0aW1hdGVkIFVzaW5nIHRoZSBTYW1wbGUgTWVhbiwgU0Qgd2FzIEVzdGltYXRlZCBVc2luZyBTYW1wbGUgU3RkLiBEZXYuIikKCiMgUmV3cml0ZSBtMiBhcyB0aGUgb3B0aW1hbCBwYXJhbWV0ZXJzIG9mIHNrZXcgbm9ybWFsCnNuX3BhcmFtcyA9IG0yJHBhcgoKIyBEaXNwbGF5IHRoZSBvcHRpbWFsIHNrZXctbm9ybWFsIHBhcmFtZXRlcnMKc25fcGFyYW1fZGYgPSBhcy5tYXRyaXgodChzbl9wYXJhbXMpKQojIHNuX3BhcmFtX2RmCiMgcm93bmFtZXMoc25fcGFyYW1fZGYpIDwtIGMoIk9wdGltYWwgUGFyYW1ldGVycyIpCiMgY29sbmFtZXMoc25fcGFyYW1fZGYpIDwtIGMoIkxvY2F0aW9uIiwgIlNjYWxlIiwgIlNoYXBlIikKCiMgRGlzcGxheSBhIHByZXR0eSB0YWJsZQojIHNuX3BhcmFtX2RmICU+JSBrYWJsZShjYXB0aW9uID0gIk9wdGltYWwgUGFyYW1ldGVycyBmb3IgdGhlIFNrZXcgTm9ybWFsIERpc3RyaWJ1dGlvbiIsIGRpZ2l0cyA9IDQpICU+JSBrYWJsZV9zdHlsaW5nKCJzdHJpcGVkIiwgZnVsbF93aWR0aCA9IEYpICU+JSBrYWJsZV9zdHlsaW5nKCkgJT4lIGZvb3Rub3RlKGdlbmVyYWwgPSAiRXN0aW1hdGVkIFVzaW5nIE1heGltdW0gTGlrZWxpaG9vZCIpCgojIGd1bV9wYXJhbSRtbGUKCiMgRGlzcGxheSB0aGUgb3B0aW1hbCBHdW1iZWwgcGFyYW1ldGVycwpndW1fcGFyYW1fZGYgPSBhcy5tYXRyaXgodChjKGd1bV9wYXJhbSRtbGUsMCkpKQojIGd1bV9wYXJhbV9kZgojIHJvd25hbWVzKGd1bV9wYXJhbV9kZikgPC0gYygiT3B0aW1hbCBQYXJhbWV0ZXJzIikKIyBjb2xuYW1lcyhndW1fcGFyYW1fZGYpIDwtIGMoIkxvY2F0aW9uIiwgIlNjYWxlIikKCiMgRGlzcGxheSBhIHByZXR0eSB0YWJsZQojIGd1bV9wYXJhbV9kZiAlPiUga2FibGUoY2FwdGlvbiA9ICJPcHRpbWFsIFBhcmFtZXRlcnMgZm9yIHRoZSBHdW1iZWwgRGlzdHJpYnV0aW9uIiwgZGlnaXRzID0gNCkgJT4lIGthYmxlX3N0eWxpbmcoInN0cmlwZWQiLCBmdWxsX3dpZHRoID0gRikgJT4lIGthYmxlX3N0eWxpbmcoKSAlPiUgZm9vdG5vdGUoZ2VuZXJhbCA9ICJFc3RpbWF0ZWQgVXNpbmcgTWF4aW11bSBMaWtlbGlob29kIikKCgojIFRha2Ugb3V0IHRoZSBvcHRpbWFsIHBhcmFtZXRlcnMKZ2V2X3BhcmFtX2RmID0gYXMubWF0cml4KHQoZ2V2X3BhcmFtJG1sZSkpCiMgcm93bmFtZXMoZ2V2X3BhcmFtX2RmKSA8LSBjKCJPcHRpbWFsIFBhcmFtZXRlcnMiKQojIGNvbG5hbWVzKGdldl9wYXJhbV9kZikgPC0gYygiTG9jYXRpb24iLCAiU2NhbGUiLCAiU2hhcGUiKQoKIyBEaXNwbGF5IGEgcHJldHR5IHRhYmxlCiMgZ2V2X3BhcmFtX2RmICU+JSBrYWJsZShjYXB0aW9uID0gIk9wdGltYWwgUGFyYW1ldGVycyBmb3IgdGhlIEdlbmVyYWxpemVkIEV4dHJlbWUgVmFsdWUgRGlzdHJpYnV0aW9uIiwgZGlnaXRzID0gMikgJT4lIGthYmxlX3N0eWxpbmcoInN0cmlwZWQiLCBmdWxsX3dpZHRoID0gRikgJT4lIGthYmxlX3N0eWxpbmcoKSAlPiUgZm9vdG5vdGUoZ2VuZXJhbCA9ICJFc3RpbWF0ZWQgVXNpbmcgTWF4aW11bSBMaWtlbGlob29kIikKCiMgQ29tYmluZSBhbGwgb2YgdGhlIGV4dHJlbWUgdmFsdWUgZGlzdHJpYnV0aW9ucyB0b2dldGhlcgpldl9wYXJhbV9kZiA9IGFzLmRhdGEuZnJhbWUocmJpbmQoc25fcGFyYW1fZGYsIGd1bV9wYXJhbV9kZiwgZ2V2X3BhcmFtX2RmKSkKcm93bmFtZXMoZXZfcGFyYW1fZGYpIDwtIGMoIlNrZXcgTm9ybWFsIiwgIkd1bWJlbCIsICJHRVYiKQpjb2xuYW1lcyhldl9wYXJhbV9kZikgPC0gYygiTG9jYXRpb24iLCAiU2NhbGUiLCAiU2hhcGUiKQoKIyBBZGQgYSBtaXNzaW5nIHZhbHVlIGZvciBHdW1iZWwgc2hhcGUKZXZfcGFyYW1fZGZbMiwzXSA8LSBOQQoKIyBEaXNwbGF5IGEgcHJldHR5IHRhYmxlCmV2X3BhcmFtX2RmICU+JSBrYWJsZShjYXB0aW9uID0gIk9wdGltYWwgUGFyYW1ldGVycyBmb3IgdGhlIENhbmRpZGF0ZSBEaXN0cmlidXRpb25zIiwgZGlnaXRzID0gMykgJT4lIGthYmxlX3N0eWxpbmcoInN0cmlwZWQiLCBmdWxsX3dpZHRoID0gRikgJT4lIGthYmxlX3N0eWxpbmcoKSAlPiUgZm9vdG5vdGUoZ2VuZXJhbCA9ICJFc3RpbWF0ZWQgVXNpbmcgTWF4aW11bSBMaWtlbGlob29kIikKCgpgYGAKClRvIGV2YWx1YXRlIHRoZSBtb2RlbCBmaXQgbW9yZSByaWdvcm91c2x5LCBJIGNvbXBhcmVkIHRoZSBLdWxsYmFjay1MZWlibGVyIGRpdmVyZ2VuY2UgZm9yIGVhY2ggdGhlb3JldGljYWwgZGlzdHJpYnV0aW9uLgoKYGBge3J9CiMgRmlyc3QsIGZpbmQgdGhlIGRlbnNpdHkgb2YgdGhlIGRhdGEKbTNfZGVuID0gaGlzdChzbWFsbF9kZlssM10sIGJyZWFrcyA9IDI1LCBmcmVxID0gRkFMU0UsIHBsb3QgPSBGQUxTRSkKIyA/aGlzdAojIG0zX2RlbiRkZW5zaXR5CgojIFJld3JpdGUgbTIgYXMgdGhlIG9wdGltYWwgcGFyYW1ldGVycyBvZiBza2V3IG5vcm1hbAojIHNuX3BhcmFtcyA9IG0yJHBhcgojIHNuX3BhcmFtcwoKIyBOZXh0IGNvbXB1dGUgdGhlIHByb2JhYmlsaXR5IGF0IGVhY2ggcG9pbnQgZm9yIHRoZSBmaXR0ZWQgbW9kZWxzCiMjIFNrZXctbm9ybWFsCnNrbl9kZW4gPSBkc25vcm0obTNfZGVuJG1pZHMsIG1lYW4gPSBtMiRwYXJbMV0sIHNkID0gbTIkcGFyWzJdLCB4aSA9IG0yJHBhclszXSkKIyMgR3VtYmVsCmd1bWJfZGVuID0gZGd1bWJlbChtM19kZW4kbWlkcywgbG9jID0gZ3VtX3BhcmFtJG1sZVsxXSwgc2NhbGUgPSBndW1fcGFyYW0kbWxlWzJdKQojIyBHRVYKZ2V2X2RlbiA9IGRnZXYobTNfZGVuJG1pZHMsIGxvYyA9IGdldl9wYXJhbSRtbGVbMV0sIHNjYWxlID0gZ2V2X3BhcmFtJG1sZVsyXSwgc2hhcGUgPSBnZXZfcGFyYW0kbWxlWzNdKQoKIyBDYWxjdWxhdGUgdGhlIEstTCBkaXZlcmdlbmNlcyBmb3IgZWFjaAprbF9za24gPSBLTEQobTNfZGVuJGRlbnNpdHksIHNrbl9kZW4pCmtsX2d1bWIgPSBLTEQobTNfZGVuJGRlbnNpdHksIGd1bWJfZGVuKQprbF9nZXYgPSBLTEQobTNfZGVuJGRlbnNpdHksIGdldl9kZW4pCgojIENvbWJpbmUgaW50byBhIGRhdGEgZnJhbWUKa2xfZGYgPSBhcy5kYXRhLmZyYW1lKGNiaW5kKGtsX3NrbiRtZWFuLnN1bS5LTEQsIGtsX2d1bWIkbWVhbi5zdW0uS0xELCBrbF9nZXYkbWVhbi5zdW0uS0xEKSkKCnJvd25hbWVzKGtsX2RmKSA8LSBjKCJNZWFuIFN1bSBLLUwgRGl2ZXJnZW5jZSIpCmNvbG5hbWVzKGtsX2RmKSA8LSBjKCJTa2V3LU5vcm1hbCIsICJHdW1iZWwiLCAiR0VWIikKCiMgRGlzcGxheSBhIHByZXR0eSB0YWJsZQprbF9kZiAlPiUga2FibGUoY2FwdGlvbiA9ICJDb21wYXJpbmcgSy1MIERpdmVyZ2VuY2VzIEJ5IE1vZGVsIEZpdHMiLCBkaWdpdHMgPSAyKSAlPiUga2FibGVfc3R5bGluZygic3RyaXBlZCIsIGZ1bGxfd2lkdGggPSBGKSAlPiUga2FibGVfc3R5bGluZygpIApgYGAKCkJhc2VkIG9uIHRoZSBLLUwgRGl2ZXJnZW5jZSwgaXQgd291bGQgc2VlbSB0byBtYWtlIHNlbnNlIHRvIHVzZSB0aGUgZ2VuZXJhbGl6ZWQgZXh0cmVtZSB2YWx1ZSBkaXN0cmlidXRpb24sIGhvd2V2ZXIsIHRoZSBwcm9ibGVtIHdpdGggZG9pbmcgdGhpcyBpcyB0aGUgZmFjdCB0aGF0IHRoaXMgZGlzdHJpYnV0aW9uIGRvZXNuJ3QgaGF2ZSBzdXBwb3J0IG92ZXIgdGhlIGVudGlyZSByZWFsIGxpbmUuIE1vcmVvdmVyLCB0aGUgU2tldy1Ob3JtYWwgZGlzdHJpYnV0aW9uIGRpZCBub3Qgd29yayB3ZWxsIHdoZW4gZml0dGluZyB0aGUgSGlkZGVuIE1hcmtvdiBNb2RlbC4gVGhlcmVmb3JlLCB0aGUgR3VtYmVsIGlzIHVzZWQgaW4gZml0dGluZyB0aGUgSE1NIGJlbG93LgoKIyMgSE1NIEJhY2tncm91bmQgYW5kIFJlc3VsdHMKClRoZSBtb3RpdmF0aW5nIGlkZWEgYmVoaW5kIGEgSGlkZGVuIE1hcmtvdiBNb2RlbCBpcyB0aGF0IHRoZXJlIGFyZSAyIHVua25vd24gbGF0ZW50IHN0YXRlcyAkayQgdGhhdCBnZW5lcmF0ZSB0aGUgZGF0YSB0aGF0IGlzIHNlZW4uIChUaGUgcmVmZXJlbmNlIGZvciB0aGlzIGluZm9ybWF0aW9uIGlzIGdpdmVuIGhlcmUgW0BTdGVwaGVuczIwMThdKS4gVGhlIGFsZ29yaXRobSBpbXBsZW1lbnRlZCBoZXJlIGNvbXB1dGVzIGZvcndhcmRzIHByb2JhYmlsaXRpZXMsICRcYWxwaGFfe3RrfSA9IFxtYXRoYmJ7UH0oWF8xLCAuLi4gLCBYX3Q7IFpfdCA9IGspJC4gVG8gc3RhcnQsIG9uZSBzaW1wbHkgbXVsdGlwbGllcyBhbiBlcXVhbGx5LXdlaWdodGVkIHByaW9yICRccGlfayA9IDAuNSQgYnkgdGhlIGxpa2VsaWhvb2Qgb2YgdGhlIGRhdGEgZ2l2ZW4gZWFjaCBzdGF0ZSwgZ2l2ZW4gYnkgJFxtYXRoYmJ7UH0oWF8xIHwgWl8xID0gayQpLiAKClRoZSBsaWtlbGlob29kIGZ1bmN0aW9uIGZvciB0aGUgInJhdGlvbmFsIiBzdGF0ZSAocmVwcmVzZW50ZWQgYnkgdGhlIG11bHRpdmFyaWF0ZSBDQVZpYVIgbW9kZWwpIGlzIHJlcHJlc2VudGVkIGJ5IGEgbm9ybWFsIGRpc3RyaWJ1dGlvbiB3aGVyZWFzIHRoZSBsaWtlbGlob29kIGZ1bmN0aW9uIGZvciB0aGUgImlycmF0aW9uYWwiIHN0YXRlIChyZXByZXNlbnRlZCBieSB0aGUgdW5pdmFyaWF0ZSBDQVZpYVIgbW9kZWwpIGlzIHJlcHJlc2VudGVkIGJ5IHRoZSBHdW1iZWwgZGlzdHJpYnV0aW9uLiBCb3RoIHVzZSB0aGUgcGFyYW1ldGVycyBlc3RpbWF0ZWQgYWJvdmUuCgpOb3csIG9uY2UgdGhlICRcYWxwaGFfMSQgdmFsdWUgaXMgY2FsY3VsYXRlLCAkXGFscGhhXzIkIGlzIGNhbGN1bGF0ZWQgYXMgZm9sbG93cywgd2l0aCBhIHNpbWlsYXIgcHJvY2VzcyBmb3IgYW4gYXJiaXRyYXJ5IHZhbHVlICRcYWxwaGFfdCQuCgokJApcYWxwaGFfMiA9IChcYWxwaGFfMSBQKV9rIFxtYXRoYmJ7UH0oWF8yIHwgWl8yID0gaykKJCQKClRoZSAkUCQgc3ltYm9sIGNvcnJlc3BvbmRzIHRvIGEgc3ltbWV0cmljIDJ4MiB0cmFuc2l0aW9uIG1hdHJpeCB3aGVyZSB0aGUgZmlyc3Qgcm93IGlzICQoMC45LCAwLjEpJCBhbmQgdGhlIHNlY29uZCByb3cgaXMgJCgwLjEsIDAuOSkkLgoKClRvIGNvbXB1dGUgdGhlIGJhY2t3YXJkcyBwcm9iYWJpbGl0aWVzLCB3ZSBjb21wdXRlIHRoZSBmb2xsb3dpbmcgJFxiZXRhX3t0a30gPSBcbWF0aGJie1B9KFhfe3QrMX0sIC4uLiAsIFhfVDsgWl90ID0gaykkLCBhbmQgdGhlbiB0aGUgcG9zdGVyaW9yIGRpc3RyaWJ1dGlvbiBmb3IgZWFjaCBzdGF0ZSAkWl90JCBpcyBnaXZlbiBieSB0aGUgZm9sbG93aW5nOgoKJCQKXG1hdGhiYntQfShaX3QgPSBrfCBYXzEsIC4uLiwgWF9UKSA9IFxhbHBoYV97dGt9IFxiZXRhX3t0a30gLyBcc3VtX3trfVxhbHBoYV97dGt9IFxiZXRhX3t0a30KJCQKCmBgYHtyfQojICMgQmVsb3cgYXJlIHRoZSBvcHRpbWFsIHBhcmFtZXRlcnMgZm9yIHRoZSBzZWNvbmQgbW9kZWwKIyBub3JtX3BhcmFtX2RmID0gYXMuZGF0YS5mcmFtZShjYmluZChtZWFuKHNtYWxsX2RmWywyXSksc2Qoc21hbGxfZGZbLDJdKSkpCiMgcm93bmFtZXMobm9ybV9wYXJhbV9kZikgPC0gYygiT3B0aW1hbCBQYXJhbWV0ZXJzIikKIyBjb2xuYW1lcyhub3JtX3BhcmFtX2RmKSA8LSBjKCJNZWFuIiwgIlN0YW5kYXJkIERldmlhdGlvbiIpCiMgCiMgIyBEaXNwbGF5IGEgcHJldHR5IHRhYmxlCiMgbm9ybV9wYXJhbV9kZiAlPiUga2FibGUoY2FwdGlvbiA9ICJPcHRpbWFsIFBhcmFtZXRlcnMgZm9yIHRoZSBOb3JtYWwgRGlzdHJpYnV0aW9uIiwgZGlnaXRzID0gMikgJT4lIGthYmxlX3N0eWxpbmcoInN0cmlwZWQiLCBmdWxsX3dpZHRoID0gRikgJT4lIGthYmxlX3N0eWxpbmcoKSAlPiUgZm9vdG5vdGUoZ2VuZXJhbCA9ICJUaGUgTWVhbiBXYXMgRXN0aW1hdGVkIFVzaW5nIHRoZSBTYW1wbGUgTWVhbiwgU0Qgd2FzIEVzdGltYXRlZCBVc2luZyBTYW1wbGUgU3RkLiBEZXYuIikKIyAKIyAjIHNuX3BhcmFtcwojIAojICMgRGlzcGxheSB0aGUgb3B0aW1hbCBza2V3LW5vcm1hbCBwYXJhbWV0ZXJzCiMgc25fcGFyYW1fZGYgPSBhcy5kYXRhLmZyYW1lKHQoc25fcGFyYW1zKSkKIyByb3duYW1lcyhzbl9wYXJhbV9kZikgPC0gYygiT3B0aW1hbCBQYXJhbWV0ZXJzIikKIyBjb2xuYW1lcyhzbl9wYXJhbV9kZikgPC0gYygiTG9jYXRpb24iLCAiU2NhbGUiLCAiU2hhcGUiKQojIAojICMgRGlzcGxheSBhIHByZXR0eSB0YWJsZQojIHNuX3BhcmFtX2RmICU+JSBrYWJsZShjYXB0aW9uID0gIk9wdGltYWwgUGFyYW1ldGVycyBmb3IgdGhlIFNrZXcgTm9ybWFsIERpc3RyaWJ1dGlvbiIsIGRpZ2l0cyA9IDQpICU+JSBrYWJsZV9zdHlsaW5nKCJzdHJpcGVkIiwgZnVsbF93aWR0aCA9IEYpICU+JSBrYWJsZV9zdHlsaW5nKCkgJT4lIGZvb3Rub3RlKGdlbmVyYWwgPSAiRXN0aW1hdGVkIFVzaW5nIE1heGltdW0gTGlrZWxpaG9vZCIpCiMgCiMgIyBndW1fcGFyYW0kbWxlCiMgCiMgIyBEaXNwbGF5IHRoZSBvcHRpbWFsIEd1bWJlbCBwYXJhbWV0ZXJzCiMgZ3VtX3BhcmFtX2RmID0gYXMuZGF0YS5mcmFtZSh0KGd1bV9wYXJhbSRtbGUpKQojIHJvd25hbWVzKGd1bV9wYXJhbV9kZikgPC0gYygiT3B0aW1hbCBQYXJhbWV0ZXJzIikKIyBjb2xuYW1lcyhndW1fcGFyYW1fZGYpIDwtIGMoIkxvY2F0aW9uIiwgIlNjYWxlIikKIyAKIyAjIERpc3BsYXkgYSBwcmV0dHkgdGFibGUKIyBndW1fcGFyYW1fZGYgJT4lIGthYmxlKGNhcHRpb24gPSAiT3B0aW1hbCBQYXJhbWV0ZXJzIGZvciB0aGUgR3VtYmVsIERpc3RyaWJ1dGlvbiIsIGRpZ2l0cyA9IDQpICU+JSBrYWJsZV9zdHlsaW5nKCJzdHJpcGVkIiwgZnVsbF93aWR0aCA9IEYpICU+JSBrYWJsZV9zdHlsaW5nKCkgJT4lIGZvb3Rub3RlKGdlbmVyYWwgPSAiRXN0aW1hdGVkIFVzaW5nIE1heGltdW0gTGlrZWxpaG9vZCIpCiMgCiMgCiMgIyBUYWtlIG91dCB0aGUgb3B0aW1hbCBwYXJhbWV0ZXJzCiMgZ2V2X3BhcmFtX2RmID0gYXMuZGF0YS5mcmFtZSh0KGdldl9wYXJhbSRtbGUpKQojIHJvd25hbWVzKGdldl9wYXJhbV9kZikgPC0gYygiT3B0aW1hbCBQYXJhbWV0ZXJzIikKIyBjb2xuYW1lcyhnZXZfcGFyYW1fZGYpIDwtIGMoIkxvY2F0aW9uIiwgIlNjYWxlIiwgIlNoYXBlIikKIyAKIyAjIERpc3BsYXkgYSBwcmV0dHkgdGFibGUKIyBnZXZfcGFyYW1fZGYgJT4lIGthYmxlKGNhcHRpb24gPSAiT3B0aW1hbCBQYXJhbWV0ZXJzIGZvciB0aGUgR2VuZXJhbGl6ZWQgRXh0cmVtZSBWYWx1ZSBEaXN0cmlidXRpb24iLCBkaWdpdHMgPSAyKSAlPiUga2FibGVfc3R5bGluZygic3RyaXBlZCIsIGZ1bGxfd2lkdGggPSBGKSAlPiUga2FibGVfc3R5bGluZygpICU+JSBmb290bm90ZShnZW5lcmFsID0gIkVzdGltYXRlZCBVc2luZyBNYXhpbXVtIExpa2VsaWhvb2QiKQpgYGAKCgoKCmBgYHtyfQojIENsZWFuIG91dCBvbGQgdmFyaWFibGVzCiMgcm0obGlzdD1scygpKQoKIyBUaGlzIGlzIHRoZSB0cnVlIG1vZGVsIHVzZWQgaW4gdGhlIHNpbXVsYXRpb24gc3R1ZHkuIFdlIHdvbid0IG5lZWQgaXQuCiMgc2V0LnNlZWQoMSkKIyBUID0gMjAwCiMgSyA9IDIKIyBzZD0gMC40CiMgUCA9IGNiaW5kKGMoMC45LDAuMSksYygwLjEsMC45KSkKCiMgU2ltdWxhdGUgdGhlIGxhdGVudCAoSGlkZGVuKSBNYXJrb3Ygc3RhdGVzCiMgQWxzbyBub3QgbmVlZGVkLgojIFogPSByZXAoMCxUKQojIFpbMV0gPSAxCiMgZm9yKHQgaW4gMTooVC0xKSl7CiMgICBaW3QrMV0gPSBzYW1wbGUoSywgc2l6ZT0xLCBwcm9iPVBbWlt0XSxdKQojIH0KCgojIFNpbXVsYXRlIHRoZSBlbWl0dGVkL29ic2VydmVkIHZhbHVlcwojIFg9IHJub3JtKFQsbWVhbj1aLHNkPXNkKQojIFgKCiMgcGxvdChYLCBtYWluPSJSZWFsaXphdGlvbiBvZiBITU07IGxhdGVudCBzdGF0ZXMgc2hvd24gaW4gcmVkIikKIyBsaW5lcyhaLGNvbD0yLGx3ZD0yKQoKIyBJbnN0ZWFkLCBsZXQncyBzdWJzZXQgb3VyIGRhdGEgZnJhbWUKIyBzbWFsbF90ZXN0ID0gdGVzdF9sb3NzWyxjKDEsNSldCiMgY29sU3VtcyhzbWFsbF90ZXN0KQoKIyBTZXQgYSB2YWx1ZSBvZiBUIGFuZCBLClQgPSBucm93KHNtYWxsX2RmKQpLID0gbmNvbChzbWFsbF9kZikgLSAxCgojIHNtYWxsX2RmCgojIEFzc2lnbiBhIHZhbHVlIG9mIFAKUCA9IGNiaW5kKGMoMC45LDAuMSksYygwLjEsMC45KSkKCiMgUGxvdCB0aGVzZSBkYXRhCiMgP2hpc3QKIyBwYXIobWZyb3c9IGMoMSwyKSkKIyBoaXN0KHNtYWxsX3Rlc3RbLDFdLCBicmVha3MgPSAyNSkKIyBoaXN0KHNtYWxsX3Rlc3RbLDJdLCBicmVha3MgPSAyNSkKIyAKIyAjIFRyYW5zZm9ybSB0aGUgZGF0YXNldAojIGxvZ190ZXN0ID0gbG9nKHNtYWxsX3Rlc3QpCiMgCiMgIyBQbG90IHRoZSBsb2dzPwojIHBhcihtZnJvdz0gYygxLDIpKQojIGg9IGhpc3QobG9nX3Rlc3RbLDFdLCBicmVha3MgPSAyNSkKIyAjIE92ZXJzZXQgYSBkZW5zaXR5IGZ1bmN0aW9uCiMgeGZpdDwtc2VxKG1pbihsb2dfdGVzdFssMV0pLG1heChsb2dfdGVzdFssMV0pLGxlbmd0aD00MCkKIyB5Zml0PC1kbm9ybSh4Zml0LG1lYW49bWVhbihsb2dfdGVzdFssMV0pLHNkPXNkKGxvZ190ZXN0WywxXSkpCiMgeWZpdCA8LSB5Zml0KmRpZmYoaCRtaWRzWzE6Ml0pKmxlbmd0aChsb2dfdGVzdFssMV0pCiMgbGluZXMoeGZpdCwgeWZpdCwgY29sPSJibHVlIiwgbHdkPTIpCiMgCiMgIyBSZXBlYXQgdGhlIHNhbWUgdGhpbmcKIyBoPSBoaXN0KGxvZ190ZXN0WywyXSwgYnJlYWtzID0gMjUpCiMgIyBPdmVyc2V0IGEgZGVuc2l0eSBmdW5jdGlvbgojIHhmaXQ8LXNlcShtaW4obG9nX3Rlc3RbLDJdKSxtYXgobG9nX3Rlc3RbLDJdKSxsZW5ndGg9NDApCiMgeWZpdDwtZG5vcm0oeGZpdCxtZWFuPW1lYW4obG9nX3Rlc3RbLDJdKSxzZD1zZChsb2dfdGVzdFssMl0pKQojIHlmaXQgPC0geWZpdCpkaWZmKGgkbWlkc1sxOjJdKSpsZW5ndGgobG9nX3Rlc3RbLDJdKQojIGxpbmVzKHhmaXQsIHlmaXQsIGNvbD0iYmx1ZSIsIGx3ZD0yKQojIAojIAojICMgRmluZCB0aGUgbWVhbnMgYW5kIFNEcwojIHYxID0gcmJpbmQobWVhbihsb2dfdGVzdFssMV0pLCBzZChsb2dfdGVzdFssMV0pKQojIAojICMgRmluZCB0aGUgbWVhbnMgYW5kIFNEcwojIHYyID0gcmJpbmQobWVhbihsb2dfdGVzdFssMl0pLCBzZChsb2dfdGVzdFssMl0pKQojIAojICMgU3RvcmUgYXMgYSBkYXRhIGZyYW1lCiMgc3VtX2RmID0gYXMuZGF0YS5mcmFtZShjYmluZCh2MSx2MikpCiMgcm93bmFtZXMoc3VtX2RmKSA8LSBjKCJNZWFuIiwgIlNEIikKIyBjb2xuYW1lcyhzdW1fZGYpIDwtIGMoIk5vIEFSIiwgIlNBViIpCiMgCiMgIyBGb3JtYXQgbmljZWx5CiMgc3VtX2RmICU+JSBrYWJsZShjYXB0aW9uID0gIlN1bW1hcnkgU3RhdGlzdGljcyBmb3IgdGhlIExvZyBvZiBMb3NzZXMgZnJvbSBFYWNoIE1vZGVsIiwgZGlnaXRzID0gMikgJT4lIGthYmxlX3N0eWxpbmcoInN0cmlwZWQiLCBmdWxsX3dpZHRoID0gRikgJT4lIGthYmxlX3N0eWxpbmcoKQoKIyBsb2dfdGVzdAoKCmBgYAoKCgoKYGBge3J9CiMgdGhpcyBpcyB0aGUgZnVuY3Rpb24gUHIoWF90IHwgWl90PWspIGZvciBvdXIgZXhhbXBsZQojIFRoaXMgaXMgdGhlIGVtaXNzaW9uIHByb2JhYmlsaXR5IGluIHRoZSAicmF0aW9uYWwgd29ybGQiLCBtb2RpZmllZCBmb3Igd2hldGhlciB3ZSBtaXNzIHBvc2l0aXZlIG9yIG5lZ2F0aXZlCmVtaXRfbm9ybSA9IGZ1bmN0aW9uKG9icyxtZWFuLCBzZCl7IAogIGRub3JtKG9icywgbWVhbiA9IG1lYW4sIHNkID0gc2QpCiAgIyBkbm9ybSh4LG1lYW49ayxzZD1zZCkKfQoKIyBIZXJlIGlzIHdoZXJlIHdlIHdpbGwgaW5wdXQgb3VyIGVtaXNzaW9uIHByb2JhYmlsaXRpZXMgZm9yIGEgR0VWCmVtaXRfZ2V2ID0gZnVuY3Rpb24ob2JzLGxvYywgc2NhbGUsIHNoYXBlKXsgCiAgZGdldihvYnMsIGxvYyA9IGxvYywgc2NhbGUgPSBzY2FsZSwgc2hhcGUgPSBzaGFwZSkKfQoKIyBUaGUgR0VWIGRvZXNuJ3QgaGF2ZSBzdXBwb3J0IG92ZXIgYWxsIG9mIHRoZSByZWFsIGxpbmUsIHdoaWNoIGlzIGEgcHJvYmxlbQplbWl0X3NuID0gZnVuY3Rpb24ob2JzLGxvYywgc2NhbGUsIHNoYXBlKXsgCiAgZHNub3JtKG9icywgbWVhbiA9IGxvYywgc2QgPSBzY2FsZSwgeGkgPSBzaGFwZSkKfQoKIyBMZXQncyB0cnkgdGhlIEd1bWJlbCBkaXN0cmlidXRpb24KZW1pdF9ndW1iID0gZnVuY3Rpb24ob2JzLGxvYywgc2NhbGUpeyAKICBkZ3VtYmVsKG9icywgbG9jID0gbG9jLCBzY2FsZSA9IHNjYWxlKQp9CgojIHNuX3BhcmFtX2RmCgojIE91ciBwcmlvciBpcyB0aGF0IGJvdGggc3RhdGVzIGFyZSBlcXVhbGx5IGxpa2VseS4KcHJpb3IgPSBjKDAuNSwwLjUpICNBc3N1bWVkIHByaW9yIGRpc3RyaWJ1dGlvbiBvbiBaXzEKCiMgVGhlIG1hdHJpeCB3aGVyZSB3ZSBzdG9yZSB0aGUgZm9yd2FyZHMgcHJvYmFiaWxpdGllcwphbHBoYSA9IG1hdHJpeChucm93ID0gVCxuY29sPUspCgoKIyBmb3IoayBpbiAxOkspeyAKIyAgIGFscGhhWzEsa10gPSBwcmlvcltrXSAqIGVtaXQoayxYWzFdKQojIH0KCiMgaGVhZChzbWFsbF9kZikKIyBub3JtX3BhcmFtX2RmJGBTdGFuZGFyZCBEZXZpYXRpb25gCiMgZ2V2X3BhcmFtX2RmJExvY2F0aW9uCgojIHNuX3BhcmFtX2RmJExvY2F0aW9uCmd1bV9wYXJhbV9kZiA9IGV2X3BhcmFtX2RmWzIsMToyXQojIGd1bV9wYXJhbV9kZiRMb2NhdGlvbgoKIyBJbml0aWFsaXplIGFscGhhWzEsXQpmb3IoayBpbiAxOkspewogIGlmIChrID09IDEpewogICAgIyBUaGlzIGlzIHRoZSBlbWlzc2lvbiBwcm9iYWJpbGl0eSBhc3N1bWluZyBub3JtYWxpdHkKICAgIGFscGhhWzEsa10gPSBwcmlvcltrXSAqIGVtaXRfbm9ybShvYnMgPSBzbWFsbF9kZiRTUFlbMV0sIG1lYW4gPSBub3JtX3BhcmFtX2RmJE1lYW4sIHNkID0gbm9ybV9wYXJhbV9kZiRgU3RhbmRhcmQgRGV2aWF0aW9uYCkKICB9IGVsc2UgaWYgKGsgPT0gMil7CiAgICAjIFRoaXMgaXMgdGhlIGVtaXNzaW9uIHByb2JhYmlsaXR5IGFzc3VtaW5nIEdFVgogICAgIyBhbHBoYVsxLGtdID0gcHJpb3Jba10gKiBlbWl0X2dldihvYnMgPSBzbWFsbF9kZiRTUFlbMV0sIGxvYyA9IGdldl9wYXJhbV9kZiRMb2NhdGlvbiwgc2NhbGUgPSBnZXZfcGFyYW1fZGYkU2NhbGUsIHNoYXBlID0gZ2V2X3BhcmFtX2RmJFNoYXBlKQogICAgIyBUaGlzIGlzIHRoZSBlbWlzc2lvbiBwcm9iYWJpbGl0eSBhc3N1bWluZyBTTgogICAgIyBhbHBoYVsxLGtdID0gcHJpb3Jba10gKiBlbWl0X3NuKG9icyA9IHNtYWxsX2RmJFNQWVsxXSwgbG9jID0gc25fcGFyYW1fZGYkTG9jYXRpb24sIHNjYWxlID0gc25fcGFyYW1fZGYkU2NhbGUsIHNoYXBlID0gc25fcGFyYW1fZGYkU2hhcGUpCiAgICAjIFRoaXJkIHRpbWUgaXMgdGhlIGNoYXJtLi4uYXNzdW1lIGEgR3VtYmVsCiAgICBhbHBoYVsxLGtdID0gcHJpb3Jba10gKiBlbWl0X2d1bWIob2JzID0gc21hbGxfZGYkU1BZWzFdLCBsb2MgPSBndW1fcGFyYW1fZGYkTG9jYXRpb24sIHNjYWxlID0gZ3VtX3BhcmFtX2RmJFNjYWxlKQogIH0gZWxzZSB7CiAgICBwcmludCgiayBzaG91bGQgbm90IGJlIGdyZWF0ZXIgdGhhbiAyIikKICB9Cn0KCiMgaGVhZChhbHBoYSkKIyBzbWFsbF9kZiRTUFlbMV0KIyBhbHBoYVsxLF0gJSolIFAKCgojIEZvcndhcmQgYWxnb3JpdGhtCmZvcih0IGluIDE6KFQtMSkpewogICMgRmluZCB0aGUgdmFsdWUgb2YgbSBhdCBlYWNoIHN0ZXAKICBtID0gYWxwaGFbdCxdICUqJSBQCiAgIyBMb29wIHRocm91Z2ggdG8gdXBkYXRlIGxldmVscyBvZiBhbHBoYQogIGZvcihrIGluIDE6Syl7CiAgICAjIGFscGhhW3QrMSxrXSA9IG1ba10qZW1pdChrLFhbdF0pIHdoYXQgSSBoYWQKICAgICMgYWxwaGFbdCsxLGtdID0gbVtrXSplbWl0KGssWFt0KzFdKSBvbmxpbmUKICAgIGlmIChrID09IDEpewogICAgICAjIGFscGhhW3QrMSxrXSA9IG1ba10qZW1pdChrLFhbdCsxXSkgb25saW5lCiAgICAgIGFscGhhW3QrMSxrXSA9IG1ba10qZW1pdF9ub3JtKG9icyA9IHNtYWxsX2RmJFNQWVt0KzFdLCBtZWFuID0gbm9ybV9wYXJhbV9kZiRNZWFuLCBzZCA9IG5vcm1fcGFyYW1fZGYkYFN0YW5kYXJkIERldmlhdGlvbmApCiAgICB9IGVsc2UgaWYgKGsgPT0gMil7CiAgICAgICMgQXNzdW1pbmcgYSBHRVYKICAgICAgIyBhbHBoYVt0KzEsa10gPSBtW2tdKmVtaXRfZ2V2KG9icyA9IHNtYWxsX2RmJFNQWVt0KzFdLCBsb2MgPSBnZXZfcGFyYW1fZGYkTG9jYXRpb24sIHNjYWxlID0gZ2V2X3BhcmFtX2RmJFNjYWxlLCBzaGFwZSA9IGdldl9wYXJhbV9kZiRTaGFwZSkKICAgICAgIyBBc3N1bWluZyBhIHNrZXctbm9ybWFsCiAgICAgICMgYWxwaGFbdCsxLGtdID0gbVtrXSplbWl0X3NuKG9icyA9IHNtYWxsX2RmJFNQWVt0KzFdLCBsb2MgPSBzbl9wYXJhbV9kZiRMb2NhdGlvbiwgc2NhbGUgPSBzbl9wYXJhbV9kZiRTY2FsZSwgc2hhcGUgPSBzbl9wYXJhbV9kZiRTaGFwZSkKICAgICAgIyBBc3N1bWluZyBhIEd1bWJlbAogICAgICBhbHBoYVt0KzEsa10gPSBtW2tdKmVtaXRfZ3VtYihvYnMgPSBzbWFsbF9kZiRTUFlbdCsxXSwgbG9jID0gZ3VtX3BhcmFtX2RmJExvY2F0aW9uLCBzY2FsZSA9IGd1bV9wYXJhbV9kZiRTY2FsZSkKICAgIH0gZWxzZSB7CiAgICAgIHByaW50KCJrIHNob3VsZCBub3QgYmUgZ3JlYXRlciB0aGFuIDIiKQogICAgfQogICAgIyBhbHBoYVt0KzEsa10gPSBtW2tdKmVtaXQob2JzID0gbG9nX3Rlc3RbdCsxLGtdLCBtZWFuID0gc3VtX2RmWzEsa10sIHNkID0gc3VtX2RmWzIsa10pCiAgfQp9CgojIGVtaXRfZ2V2KG9icyA9IHNtYWxsX2RmJFNQWVsyXSwgbG9jID0gZ2V2X3BhcmFtX2RmJExvY2F0aW9uLCBzY2FsZSA9IGdldl9wYXJhbV9kZiRTY2FsZSwgc2hhcGUgPSBnZXZfcGFyYW1fZGYkU2hhcGUpCiMgZW1pdF9zbihvYnMgPSBzbWFsbF9kZiRTUFlbMl0sIGxvYyA9IHNuX3BhcmFtX2RmJExvY2F0aW9uLCBzY2FsZSA9IHNuX3BhcmFtX2RmJFNjYWxlLCBzaGFwZSA9IHNuX3BhcmFtX2RmJFNoYXBlKQojIHNuX3BhcmFtX2RmJExvY2F0aW9uCiMgc25fcGFyYW1fZGYkU2NhbGUKIyBzbl9wYXJhbV9kZiRTaGFwZQoKIyBkc25vcm0oc21hbGxfZGYkU1BZWzJdLCBtZWFuID0gc25fcGFyYW1fZGYkTG9jYXRpb24sIHNkID0gc25fcGFyYW1fZGYkU2NhbGUsIHhpID0gc25fcGFyYW1fZGYkU2hhcGUpCiMgaGlzdChyc25vcm0oMTAwMDAsIG1lYW4gPSBzbl9wYXJhbV9kZiRMb2NhdGlvbiwgc2QgPSBzbl9wYXJhbV9kZiRTY2FsZSwgeGkgPSBzbl9wYXJhbV9kZiRTaGFwZSksIHhsaW0gPSBjKC0yLDApKQoKIyBUcnkgaXQgd2l0aCBhIGd1bWJlbAojIGRndW1iZWwoc21hbGxfZGYkU1BZWzNdLCBsb2MgPSBndW1fcGFyYW1fZGYkTG9jYXRpb24sIHNjYWxlID0gZ3VtX3BhcmFtX2RmJFNjYWxlKQoKIyBzbWFsbF9kZiRTUFlbMl0KCiMgYWxwaGEKCmBgYAoKCmBgYHtyfQojIEluaXRhbGl6ZSBhIGJldGEgbWF0cml4CmJldGEgPSBtYXRyaXgobnJvdyA9IFQsbmNvbD1LKQoKIyBJbml0aWFsaXplIGJldGEKZm9yKGsgaW4gMTpLKXsKICBiZXRhW1Qsa10gPSAxCn0KCiMgQmFja3dhcmRzIGFsZ29yaXRobQpmb3IodCBpbiAoVC0xKToxKXsKICBmb3IoayBpbiAxOkspewogICAgIyBNb2RpZnkgdGhlIHZhbHVlIG9mIGJldGEKICAgICMgYmV0YVt0LGtdID0gc3VtKGJldGFbdCsxLF0qUFtrLF0qZW1pdCgxOkssWFt0KzFdKSkKICAgICMgYmV0YVt0LGtdID0gc3VtKGJldGFbdCsxLF0qUFtrLF0qZW1pdChvYnMgPSBsb2dfdGVzdFt0KzEsa10sIG1lYW4gPSBzdW1fZGZbMSxrXSwgc2QgPSBzdW1fZGZbMixrXSkpCiAgICAjIGJldGFbdCxrXSA9IHN1bShiZXRhW3QrMSxdKlBbayxdKmVtaXQoMTpLLFhbdCsxXSkpCiAgICBpZiAoayA9PSAxKXsKICAgICAgIyBIZXJlJ3Mgd2hhdCB3YXMgb25saW5lCiAgICAgICMgYmV0YVt0LGtdID0gc3VtKGJldGFbdCsxLF0qUFtrLF0qZW1pdCgxOkssWFt0KzFdKSkKICAgICAgIyBGaW5kIHRoZSB2YWx1ZXMgc2VwYXJhdGVseQogICAgICB2MSA9IGVtaXRfbm9ybShvYnMgPSBzbWFsbF9kZiRTUFlbdCsxXSwgbWVhbiA9IG5vcm1fcGFyYW1fZGYkTWVhbiwgc2QgPSBub3JtX3BhcmFtX2RmJGBTdGFuZGFyZCBEZXZpYXRpb25gKQogICAgICB2MiA9IGVtaXRfZ3VtYihvYnMgPSBzbWFsbF9kZiRTUFlbdCsxXSwgbG9jID0gZ3VtX3BhcmFtX2RmJExvY2F0aW9uLCBzY2FsZSA9IGd1bV9wYXJhbV9kZiRTY2FsZSkKICAgICAgYmV0YVt0LGtdID0gc3VtKGJldGFbdCsxLF0qUFtrLF0qYyh2MSwgdjIpKQogICAgfSBlbHNlIGlmIChrID09IDIpewogICAgICAjIEhlcmUncyB3aGF0IHdhcyBvbmxpbmUKICAgICAgIyBGaW5kIHRoZSB2YWx1ZXMgc2VwYXJhdGVseQogICAgICB2MSA9IGVtaXRfbm9ybShvYnMgPSBzbWFsbF9kZiRTUFlbdCsxXSwgbWVhbiA9IG5vcm1fcGFyYW1fZGYkTWVhbiwgc2QgPSBub3JtX3BhcmFtX2RmJGBTdGFuZGFyZCBEZXZpYXRpb25gKQogICAgICB2MiA9IGVtaXRfZ3VtYihvYnMgPSBzbWFsbF9kZiRTUFlbdCsxXSwgbG9jID0gZ3VtX3BhcmFtX2RmJExvY2F0aW9uLCBzY2FsZSA9IGd1bV9wYXJhbV9kZiRTY2FsZSkKICAgICAgYmV0YVt0LGtdID0gc3VtKGJldGFbdCsxLF0qUFtrLF0qYyh2MSwgdjIpKQogICAgfSBlbHNlIHsKICAgICAgcHJpbnQoImsgc2hvdWxkIG5vdCBiZSBncmVhdGVyIHRoYW4gMiIpCiAgICB9CiAgfQp9CgoKCgpgYGAKCgpgYGB7cn0KIyBMYXN0bHksIHdlIG5lZWQgdG8gc29sdmUgZm9yIHRoZSBwb3N0ZXJpb3IKYWIgPSBhbHBoYSpiZXRhCnByb2IgPSBhYi9yb3dTdW1zKGFiKQojIHJvd1N1bXMocHJvYikKIyBwcm9iCgpwbG90KHByb2JbLDJdLHR5cGU9ImwiLHlsaW09YygwLDEpLCBtYWluPSJDaGFuY2UgdGhlIFdvcmxkIGlzIGluIGFuIElycmF0aW9uYWwgU3RhdGUiLGx3ZD0yLHlsYWI9IlBvc3RlcmlvciBQcm9iYWJpbGl0eSIpCiMgbGluZXMoWj09Mixjb2w9Mixsd2Q9MikKYGBgCgpgYGB7cn0KCiMgQm9sdCBvbiBhbiBOQQpub3JtX3BhcmFtX2RmMiA9IGNiaW5kKG5vcm1fcGFyYW1fZGYsIE5BKQojIFJlbmFtZSByb3dzIGFuZCBjb2x1bW5zCnJvd25hbWVzKG5vcm1fcGFyYW1fZGYyKSA8LSBjKCJOb3JtYWwiKQpjb2xuYW1lcyhub3JtX3BhcmFtX2RmMikgPC0gYygiTG9jYXRpb24iLCAiU2NhbGUiLCAiU2hhcGUiKQoKIyBDb21iaW5lIGludG8gYW4gb3B0aW1hbCBwYXJhbWV0ZXIgZGYKb3B0X3BhcmFtX2RmID0gcmJpbmQobm9ybV9wYXJhbV9kZjIsIGV2X3BhcmFtX2RmKQpvcHRfcGFyYW1fZGYkTG9jYXRpb24Kb3B0X3BhcmFtX2RmCgphYmMgPSBvcHRfcGFyYW1fZGZbYygiTm9ybWFsIiksXQphYmMkTG9jYXRpb24KYGBgCgoKYGBge3J9CiMnIEEgZnVuY3Rpb24gdG8gZml0IG11bHRpcGxlIEhNTXMgZ2l2ZW4gYW4gaW5wdXQgZGF0YXNldAojJwojJyBAcGFyYW0gaW5wdXRfZGYgLSBpbnB1dCBkYXRhZnJhbWUKIycgQHBhcmFtIHRfcHJvYiAtIHRyYW5zaXRpb24gcHJvYmFiaWxpdHkKIycgQHBhcmFtIHByaW9yX3Byb2IgLSBwcmlvciBwcm9iYWJpbGl0eQojJyBAcGFyYW0gaXJyX2Rpc3QgLSB0aGUgaXJyYXRpb25hbCBkaXN0cmlidXRpb24uIFJpZ2h0IG5vdywgdGhpcyBjb2RlIGlzIG9ubHkgc2V0IHVwIHRvIHdvcmsgd2l0aCBHdW1iZWwKIycgQHBhcmFtIHJhdF9kaXN0IC0gcmF0aW9uYWwgZGlzdHJpYnV0aW9uLiBSaWdodCBub3csIG9ubHkgZGVzaWduZWQgZm9yIG5vcm1hbC4KIycgQHBhcmFtIHJhdF9vcHRfcGFyYW0gLSBvcHRpbWFsIHBhcmFtYXRlcnMgZm9yIHRoZSByYXRpb25hbCBkaXN0cmlidXRpb24uIEZvciAyMDA4LCBpdCB3YXMgYSBub3JtYWwuCiMnIEBwYXJhbSBpcnJfb3B0X3BhcmFtIC0gb3B0aW1hbCBwYXJhbWV0ZXJzIGZvciB0aGUgaXJyYXRpb25hbCBkaXN0cmlidXRpb24uIEZvciAyMDA4LCBpdCB3YXMgYSBHdW1iZWwKIycgQHBhcmFtIHZhcl9sZXZlbCAtIHRoZSBWYVIgbGV2ZWwgdXNlZCBpbiB0aGUgcGxvdAojJwojJyBAcmV0dXJuIC0gdGhlIHByb2JhYmlsaXRpZXMgaW4gYSBuaWNlbHkgZm9ybWF0dGVkIHRhYmxlCiMnIEBleHBvcnQKIycKIycgQGV4YW1wbGVzIC0gaG1tX2ZpdChpbnB1dF9kZiA9IHNtYWxsX2RmLCB0X3Byb2IgPSAwLjEsIHByaW9yX3Byb2IgPSAwLjUsIGlycl9kaXN0ID0gIkd1bWJlbCIpCmhtbV9maXQgPSBmdW5jdGlvbihpbnB1dF9kZiwgdF9wcm9iLCBwcmlvcl9wcm9iLCByYXRfb3B0X3BhcmFtLCBpcnJfb3B0X3BhcmFtLCBpcnJfZGlzdCA9ICJHdW1iZWwiLCByYXRfZGlzdCA9ICJOb3JtYWwiLCB2YXJfbGV2ZWwpewogICMgU2V0IGEgdmFsdWUgb2YgVCBhbmQgSwogIFQgPSBucm93KGlucHV0X2RmKQogIEsgPSBuY29sKGlucHV0X2RmKSAtIDEKICAjIEluaXRpYWxpemUgb3B0aW1hbCBwYXJhbWV0ZXJzIGZvciByYXRpb25hbCBhbmQgaXJyYXRpb25hbCBkYXRhc2V0cwogIHJhdF9vcHRfcGFyYW0gPSByYXRfb3B0X3BhcmFtW2MocmF0X2Rpc3QpLF0KICBpcnJfb3B0X3BhcmFtID0gaXJyX29wdF9wYXJhbVtjKGlycl9kaXN0KSxdCiAgIyBwcmludChyYXRfb3B0X3BhcmFtKQogICMgRW5jb2RlIHRoZSBwcmlvcgogIHByaW9yID0gYyhwcmlvcl9wcm9iLCAxLSBwcmlvcl9wcm9iKSAjQXNzdW1lZCBwcmlvciBkaXN0cmlidXRpb24gb24gWl8xCiAgIyBBc3NpZ24gYSB2YWx1ZSBvZiBQIC0gdGhlIHRyYW5zaXRpb24gbWF0cml4CiAgUCA9IGNiaW5kKGMoMS10X3Byb2IsdF9wcm9iKSxjKHRfcHJvYiwxLXRfcHJvYikpCiAgIyBwcmludCgiU3RvcCAxIikKICAjIEluaXRpYWxpemUgYWxwaGFbMSxdCiAgZm9yKGsgaW4gMTpLKXsKICAgIGlmIChrID09IDEpewogICAgICAjIFRoaXMgaXMgdGhlIGVtaXNzaW9uIHByb2JhYmlsaXR5IGluIHRoZSAicmF0aW9uYWwiIHdvcmxkCiAgICAgIGFscGhhWzEsa10gPSBwcmlvcltrXSAqIGVtaXRfbm9ybShvYnMgPSBpbnB1dF9kZiRTUFlbMV0sIG1lYW4gPSByYXRfb3B0X3BhcmFtJExvY2F0aW9uLCBzZCA9IHJhdF9vcHRfcGFyYW0kU2NhbGUpCiAgICB9IGVsc2UgaWYgKGsgPT0gMil7CiAgICAgICMgVGhpcyBpcyB0aGUgZW1pc3Npb24gcHJvYmFiaWxpdHkgYXNzdW1pbmcgR0VWCiAgICAgICMgYWxwaGFbMSxrXSA9IHByaW9yW2tdICogZW1pdF9nZXYob2JzID0gc21hbGxfZGYkU1BZWzFdLCBsb2MgPSBnZXZfcGFyYW1fZGYkTG9jYXRpb24sIHNjYWxlID0gZ2V2X3BhcmFtX2RmJFNjYWxlLCBzaGFwZSA9IGdldl9wYXJhbV9kZiRTaGFwZSkKICAgICAgIyBUaGlzIGlzIHRoZSBlbWlzc2lvbiBwcm9iYWJpbGl0eSBhc3N1bWluZyBTTgogICAgICAjIGFscGhhWzEsa10gPSBwcmlvcltrXSAqIGVtaXRfc24ob2JzID0gc21hbGxfZGYkU1BZWzFdLCBsb2MgPSBzbl9wYXJhbV9kZiRMb2NhdGlvbiwgc2NhbGUgPSBzbl9wYXJhbV9kZiRTY2FsZSwgc2hhcGUgPSBzbl9wYXJhbV9kZiRTaGFwZSkKICAgICAgIyBUaGlyZCB0aW1lIGlzIHRoZSBjaGFybS4uLmFzc3VtZSBhIEd1bWJlbAogICAgICBhbHBoYVsxLGtdID0gcHJpb3Jba10gKiBlbWl0X2d1bWIob2JzID0gaW5wdXRfZGYkU1BZWzFdLCBsb2MgPSBpcnJfb3B0X3BhcmFtJExvY2F0aW9uLCBzY2FsZSA9IGlycl9vcHRfcGFyYW0kU2NhbGUpCiAgICB9IGVsc2UgewogICAgICBwcmludCgiayBzaG91bGQgbm90IGJlIGdyZWF0ZXIgdGhhbiAyIikKICAgIH0KICB9CiAgIyBGb3J3YXJkIGFsZ29yaXRobQogIGZvcih0IGluIDE6KFQtMSkpewogICAgIyBGaW5kIHRoZSB2YWx1ZSBvZiBtIGF0IGVhY2ggc3RlcAogICAgbSA9IGFscGhhW3QsXSAlKiUgUAogICAgIyBMb29wIHRocm91Z2ggdG8gdXBkYXRlIGxldmVscyBvZiBhbHBoYQogICAgZm9yKGsgaW4gMTpLKXsKICAgICAgIyBhbHBoYVt0KzEsa10gPSBtW2tdKmVtaXQoayxYW3RdKSB3aGF0IEkgaGFkCiAgICAgICMgYWxwaGFbdCsxLGtdID0gbVtrXSplbWl0KGssWFt0KzFdKSBvbmxpbmUKICAgICAgaWYgKGsgPT0gMSl7CiAgICAgICAgIyBhbHBoYVt0KzEsa10gPSBtW2tdKmVtaXQoayxYW3QrMV0pIG9ubGluZQogICAgICAgIGFscGhhW3QrMSxrXSA9IG1ba10qZW1pdF9ub3JtKG9icyA9IGlucHV0X2RmJFNQWVt0KzFdLCBtZWFuID0gcmF0X29wdF9wYXJhbSRMb2NhdGlvbiwgc2QgPSByYXRfb3B0X3BhcmFtJFNjYWxlKQogICAgICB9IGVsc2UgaWYgKGsgPT0gMil7CiAgICAgICAgIyBBc3N1bWluZyBhIEdFVgogICAgICAgICMgYWxwaGFbdCsxLGtdID0gbVtrXSplbWl0X2dldihvYnMgPSBzbWFsbF9kZiRTUFlbdCsxXSwgbG9jID0gZ2V2X3BhcmFtX2RmJExvY2F0aW9uLCBzY2FsZSA9IGdldl9wYXJhbV9kZiRTY2FsZSwgc2hhcGUgPSBnZXZfcGFyYW1fZGYkU2hhcGUpCiAgICAgICAgIyBBc3N1bWluZyBhIHNrZXctbm9ybWFsCiAgICAgICAgIyBhbHBoYVt0KzEsa10gPSBtW2tdKmVtaXRfc24ob2JzID0gc21hbGxfZGYkU1BZW3QrMV0sIGxvYyA9IHNuX3BhcmFtX2RmJExvY2F0aW9uLCBzY2FsZSA9IHNuX3BhcmFtX2RmJFNjYWxlLCBzaGFwZSA9IHNuX3BhcmFtX2RmJFNoYXBlKQogICAgICAgICMgQXNzdW1pbmcgYSBHdW1iZWwKICAgICAgICBhbHBoYVt0KzEsa10gPSBtW2tdKmVtaXRfZ3VtYihvYnMgPSBpbnB1dF9kZiRTUFlbdCsxXSwgbG9jID0gaXJyX29wdF9wYXJhbSRMb2NhdGlvbiwgc2NhbGUgPSBpcnJfb3B0X3BhcmFtJFNjYWxlKQogICAgICB9IGVsc2UgewogICAgICAgIHByaW50KCJrIHNob3VsZCBub3QgYmUgZ3JlYXRlciB0aGFuIDIiKQogICAgICB9CiAgICAgICMgYWxwaGFbdCsxLGtdID0gbVtrXSplbWl0KG9icyA9IGxvZ190ZXN0W3QrMSxrXSwgbWVhbiA9IHN1bV9kZlsxLGtdLCBzZCA9IHN1bV9kZlsyLGtdKQogICAgfQogIH0KICAjIEluaXRhbGl6ZSBhIGJldGEgbWF0cml4CiAgYmV0YSA9IG1hdHJpeChucm93ID0gVCxuY29sPUspCiAgIyBJbml0aWFsaXplIGJldGEKICBmb3IoayBpbiAxOkspewogICAgYmV0YVtULGtdID0gMQogIH0KICAjIHByaW50KCJTdG9wIDIiKQogICMgQmFja3dhcmRzIGFsZ29yaXRobQogIGZvcih0IGluIChULTEpOjEpewogICAgZm9yKGsgaW4gMTpLKXsKICAgICAgIyBNb2RpZnkgdGhlIHZhbHVlIG9mIGJldGEKICAgICAgIyBiZXRhW3Qsa10gPSBzdW0oYmV0YVt0KzEsXSpQW2ssXSplbWl0KDE6SyxYW3QrMV0pKQogICAgICAjIGJldGFbdCxrXSA9IHN1bShiZXRhW3QrMSxdKlBbayxdKmVtaXQob2JzID0gbG9nX3Rlc3RbdCsxLGtdLCBtZWFuID0gc3VtX2RmWzEsa10sIHNkID0gc3VtX2RmWzIsa10pKQogICAgICAjIGJldGFbdCxrXSA9IHN1bShiZXRhW3QrMSxdKlBbayxdKmVtaXQoMTpLLFhbdCsxXSkpCiAgICAgIGlmIChrID09IDEpewogICAgICAgICMgSGVyZSdzIHdoYXQgd2FzIG9ubGluZQogICAgICAgICMgYmV0YVt0LGtdID0gc3VtKGJldGFbdCsxLF0qUFtrLF0qZW1pdCgxOkssWFt0KzFdKSkKICAgICAgICAjIEZpbmQgdGhlIHZhbHVlcyBzZXBhcmF0ZWx5CiAgICAgICAgdjEgPSBlbWl0X25vcm0ob2JzID0gaW5wdXRfZGYkU1BZW3QrMV0sIG1lYW4gPSByYXRfb3B0X3BhcmFtJExvY2F0aW9uLCBzZCA9IHJhdF9vcHRfcGFyYW0kU2NhbGUpCiAgICAgICAgdjIgPSBlbWl0X2d1bWIob2JzID0gaW5wdXRfZGYkU1BZW3QrMV0sIGxvYyA9IGlycl9vcHRfcGFyYW0kTG9jYXRpb24sIHNjYWxlID0gaXJyX29wdF9wYXJhbSRTY2FsZSkKICAgICAgICBiZXRhW3Qsa10gPSBzdW0oYmV0YVt0KzEsXSpQW2ssXSpjKHYxLCB2MikpCiAgICAgIH0gZWxzZSBpZiAoayA9PSAyKXsKICAgICAgICAjIEhlcmUncyB3aGF0IHdhcyBvbmxpbmUKICAgICAgICAjIEZpbmQgdGhlIHZhbHVlcyBzZXBhcmF0ZWx5CiAgICAgICAgdjEgPSBlbWl0X25vcm0ob2JzID0gaW5wdXRfZGYkU1BZW3QrMV0sICBtZWFuID0gcmF0X29wdF9wYXJhbSRMb2NhdGlvbiwgc2QgPSByYXRfb3B0X3BhcmFtJFNjYWxlKQogICAgICAgIHYyID0gZW1pdF9ndW1iKG9icyA9IGlucHV0X2RmJFNQWVt0KzFdLCAgbG9jID0gaXJyX29wdF9wYXJhbSRMb2NhdGlvbiwgc2NhbGUgPSBpcnJfb3B0X3BhcmFtJFNjYWxlKQogICAgICAgIGJldGFbdCxrXSA9IHN1bShiZXRhW3QrMSxdKlBbayxdKmModjEsIHYyKSkKICAgICAgfSBlbHNlIHsKICAgICAgICBwcmludCgiayBzaG91bGQgbm90IGJlIGdyZWF0ZXIgdGhhbiAyIikKICAgICAgfQogICAgfQogIH0KICAjIExhc3RseSwgd2UgbmVlZCB0byBzb2x2ZSBmb3IgdGhlIHBvc3RlcmlvcgogIGFiID0gYWxwaGEqYmV0YQogICMgcHJpbnQocHJvYikKICBwcm9iID0gYWIvcm93U3VtcyhhYikKICAjIFBsb3QgdGhlIERhdGEgIAogIHBsb3QocHJvYlssMl0sdHlwZT0ibCIseWxpbT1jKDAsMSksIG1haW49IkNoYW5jZSB0aGUgV29ybGQgaXMgaW4gYW4gSXJyYXRpb25hbCBTdGF0ZSIsbHdkPTIseWxhYj0iUG9zdGVyaW9yIFByb2JhYmlsaXR5IiwKICAgICAgIHhsYWIgPSBwYXN0ZTAoIlRoZSAyNTAgVHJhZGluZyBEYXlzIGZyb20gIiwgbWluKGluZGV4KGlucHV0X2RmKSksICIgdG8gIiwgbWF4KGluZGV4KGlucHV0X2RmKSkpLCBzdWIgPSBwYXN0ZTAoIlRoZSBQcm9iYWJpbGl0eSBvZiBUcmFuc2l0aW9uIGlzICIsIHRfcHJvYioxMDAsICIlOyBWYVIgTGV2ZWwgaXMgIiwgdmFyX2xldmVsLCAiJSIpKQogICMgQmVhdXRpZnkgdGhlIHByb2JhYmlsaXRpZXMKICBwcm9iX2RmID0gYXMuZGF0YS5mcmFtZShwcm9iKQogICMgQm9sdCBvbiBkYXRlcwogICMgcHJvYl9kZiA9IGNiaW5kKGluZGV4KGlucHV0X2RmKSwgcHJvYl9kZikKICAjIEFkZCBjb2x1bW4gbmFtZXMKICBjb2xuYW1lcyhwcm9iX2RmKSA8LSBjKCJSYXRpb25hbCIsICJJcnJhdGlvbmFsIikKICAjIHByaW50KGRpbShpbnB1dF9kZikpCiAgIyBwcmludChsZW5ndGgoaW5kZXgoaW5wdXRfZGYpKSkKICAjIHByaW50KHByb2JfZGYpCiAgIyBBZGQgcm93bmFtZXMKICByb3duYW1lcyhwcm9iX2RmKSA8LSBpbmRleChpbnB1dF9kZikKICAjIGNvbG5hbWVzKHByb2JfZGYpIDwtIGMoIkRhdGVzIiwiUmF0aW9uYWwiLCAiSXJyYXRpb25hbCIpCiAgIyBwcmludChjYmluZChpbnB1dF9kZiwgcHJvYl9kZikpCiAgcmV0dXJuKGxpc3QocHJvYnMgPSBwcm9iX2RmLCBhbHBoYSA9IGFscGhhLCBiZXRhID0gYmV0YSkpCn0KYGBgCgpgYGB7cn0Kb3V0ID0gaG1tX2ZpdChpbnB1dF9kZiA9IHNtYWxsX2RmLCB0X3Byb2IgPSAwLjEsIHByaW9yX3Byb2IgPSAwLjUsIGlycl9kaXN0ID0gIkd1bWJlbCIsIHJhdF9vcHRfcGFyYW0gPSBub3JtX3BhcmFtX2RmMiwgaXJyX29wdF9wYXJhbSA9IGV2X3BhcmFtX2RmLCB2YXJfbGV2ZWwgPSAxKQojIGhlYWQob3V0KQojIHJvd1N1bXMob3V0KQojIGluZGV4KHNtYWxsX2RmKQoKIyBjYmluZChpbmRleChzbWFsbF9kZiksIG91dCkKYGBgCgojIEZVTkNUSU9OUwoKCmBgYHtyLCByZXN1bHRzPSAgJ2FzaXMnfQojIENhbGwgdGhlIGFib3ZlIGZ1bmN0aW9uIHRvIGltcG9ydCBkYXRhIGZyb20gbXkgdGhlc2lzCnYxXzIwMDhfYWxsZXRmMSA9IHZhcl9pbnB1dF9kaXNwKCIvVXNlcnMvc3RldmVubW9lbi9Eb2N1bWVudHMvR2l0SHViL0NBVmlhUl9NU190aGVzaXMvRGF0YV9FeHBvcnQvU1BZX2FsbF9FVEZfcnVucy8iLCJ2YXJfMXBjXzIwMDhfYWxsX2V0Zi5jc3YiLCAwLjAxLCBwcmludF9ncmFwaCA9IDAsIHByaW50X212X3RhYmxlID0gMCwgcHJpbnRfdXZfdGFibGUgPSAwLCBwcmludF9vcHRfcGFyYW0gPTApCnYxXzIwMDhfYWxsZXRmMiA9IHZhcl9pbnB1dF9kaXNwKCIvVXNlcnMvc3RldmVubW9lbi9Eb2N1bWVudHMvR2l0SHViL0NBVmlhUl9NU190aGVzaXMvRGF0YV9FeHBvcnQvU1BZX2FsbF9FVEZfcnVucy8iLCJ2YXJfMXBjXzIwMDhfYWxsX2V0Zi5jc3YiLCAwLjA1LCBwcmludF9ncmFwaCA9IDAsIHByaW50X212X3RhYmxlID0gMCwgcHJpbnRfdXZfdGFibGUgPSAwLCBwcmludF9vcHRfcGFyYW0gPTApCmBgYAoKCgpgYGB7cn0KIycgVGhpcyBpcyBhIGZ1bmN0aW9uIHRvIHJlYWQgaW4gdGhlIGxvc3NlcyBmcm9tIHByZXZpb3VzIHllYXJzCiMnCiMnIEBwYXJhbSB2YXJfbGV2ZWwgLSB0aGUgVmFSIGxldmVsIGFzIGFuIGludGVnZXIKIycgQHBhcmFtIHllYXIgLSB0aGUgeWVhciB0byByZWFkIGluLiAyMDA4LCAyMDEwLCAyMDE0LCBhbmQgMjAxNi4KIycgQHBhcmFtIHBhdGggLSB0aGUgcGF0aCB0byB0aGUgZmlsZXMuIFlvdSBwcm9iYWJseSBzaG91bGRuJ3QgY2hhbmdlIHRoaXMuCiMnCiMnIEByZXR1cm4gLSB0aGUgbG9zc2VzIGJ5IHllYXIKIycgQGV4cG9ydAojJwojJyBAZXhhbXBsZXMgLSBpbXBvcnRfZGF0KDEsIDIwMDgpCmltcG9ydF9kYXQgPSBmdW5jdGlvbih2YXJfbGV2ZWwsIHllYXIsIHBhdGggPSAiL1VzZXJzL3N0ZXZlbm1vZW4vRG9jdW1lbnRzL0dpdEh1Yi9DQVZpYVJfTVNfdGhlc2lzL0RhdGFfRXhwb3J0L1NQWV9hbGxfRVRGX3J1bnMvIil7CiAgIyBJbXBvcnQgdGhlIGRhdGEgZnJhbWUKICBpbnRfZGYgPSB2YXJfaW5wdXRfZGlzcChwYXRoLCBwYXN0ZTAoInZhcl8iLCB2YXJfbGV2ZWwsICJwY18iLCB5ZWFyLCAiX2FsbF9ldGYuY3N2IiksIDAuMDEsIHByaW50X2dyYXBoID0gMCwgcHJpbnRfbXZfdGFibGUgPSAwLCBwcmludF91dl90YWJsZSA9IDAsIHByaW50X29wdF9wYXJhbSA9MCkKICAjIEV4dHJhY3QgdGhlIGxvc3NlcwogIGxvc3NlcyA9IGdlbl9sb3NzX3Rlc3QoZGF0YV9tYXQgPSBpbnRfZGZbWzFdXSwgdGF1ID0gdmFyX2xldmVsLzEwMClbWzNdXQogICMgQXNzaWduIHRoZSBwcmVkaWN0aW9ucwogIHByZWRzID0gaW50X2RmW1sxXV0KICAjIFJldHVybiB0aGUgbG9zc2VzCiAgcmV0dXJuKGxpc3QocHJlZHMgPSBwcmVkcywgbG9zc2VzID0gbG9zc2VzKSkKfQoKIyB2MV8yMDA4X2FsbGV0ZgoKZGF0MSA9IGltcG9ydF9kYXQoMSwgMjAwOCkKIyBhYmMKIyBhYmNkZSA9Y29sU3VtcyhhYmMpCiMgYWJjZGUKIyAKIyB3aGljaC5taW4oYWJjZGVbMTo4XSkKYGBgCgoKYGBge3J9CiMnIEEgZnVuY3Rpb24gdGhhdCBjaG9vc2VzIHRoZSBvcHRpbWFsIG1vZGVscwojJwojJyBAcGFyYW0gbG9zc19tYXQgLSBsb3NzIG1hdHJpeCBmcm9tIHByZXZpb3VzIGNvZGUKIycKIycgQHJldHVybiAtIHRoZSBvcHRpbWFsIG1vZGVscyBmb3IgdGhlIEhNTQojJyBAZXhwb3J0CiMnCiMnIEBleGFtcGxlcyAtIHBpY2tfYmVzdChkYXQxKQpwaWNrX2Jlc3QgPSBmdW5jdGlvbihsb3NzX21hdCl7CiAgIyBGaW5kIHRoZSBjb2x1bW4gc3VtcwogIGNzID0gY29sU3Vtcyhsb3NzX21hdCkKICAjIFN1YnNldCBpbnRvIHR3byAtIHJhdGlvbmFsIGFuZCBpcnJhdGlvbmFsIHBhcnRzIChzcGxpdCBpbiB0d28pCiAgcmF0X3N1bSA9IGNzWzE6NF0KICBpcnJfc3VtID0gY3NbNTo4XQogICMgRmluZCB0aGUgbWluaW1pemVyIG9mIGVhY2ggc2V0CiAgcmF0X21pbiA9IHdoaWNoLm1pbihyYXRfc3VtKQogICMgQWRkIDQgZm9yIHRoZSBvZmZzZXQKICBpcnJfbWluID0gd2hpY2gubWluKGlycl9zdW0pICsgNAogICMgcHJpbnQoYyhyYXRfbWluLCBpcnJfbWluKSkKICAjIFJldHVybiB0aGUgb3B0aW1hbCBwYWlycwogIHJldHVybihjKHJhdF9taW4sIGlycl9taW4pKQp9CgpiZXN0ID0gcGlja19iZXN0KGRhdDEkbG9zc2VzKQoKYygxLGJlc3QrMSkKIyBUaGVzZSBhcmUgdGhlIGxvc3NlcyBnZW5lcmF0ZWQgZnJvbSBvdXIgZmluYWwgcnVuCiMgdGVzdF9sb3NzID0gZ2VuX2xvc3NfdGVzdChkYXRhX21hdCA9IHYxXzIwMDhfYWxsZXRmW1sxXV0sIHRhdSA9IDAuMDEpW1szXV0KCgpgYGAKCmBgYHtyfQojIFN1YnNldCB0aGUgZGF0YQoKIycgQSBmdW5jdGlvbiB0byBzdWJzZXQgdGhlIGRhdGEgYW5kIHByaW50IHRoZSBvcHRpbWFsIG1vZGVscwojJwojJyBAcGFyYW0gb3B0X3BhcmFtcyAtIHRoZSBvcHRpbWFsIHBhcmFtZXRlcnMgZnJvbSB0aGUgcGlja19iZXN0IGZ1bmN0aW9uCiMnIEBwYXJhbSBpbml0X2RmIC0gdGhlIGluaXRpYWwgZGF0YSBmcmFtZSB0byByZWFkIG9mZiBvZgojJyBAcGFyYW0gcHJpbnRfYmVzdF9tb2RzIC0gcHJpbnQgdGhlIGJlc3QgbW9kZWxzIHRoYXQgd2lsbCBnbyB0aHJvdWdoIHRoZSBvcHRpbWl6YXRpb24gcHJvY2VzcwojJwojJyBAcmV0dXJuIC0gYSBzdWJzZXR0ZWQgZGF0YSBmcmFtZQojJyBAZXhwb3J0CiMnCiMnIEBleGFtcGxlcyAtIHRlc3RfZGYgPSBzbWFsbF9kZl9mbihiZXN0LCBkYXQxJHByZWRzLCBwcmludF9iZXN0X21vZHMgPSAxKQpzbWFsbF9kZl9mbiA9IGZ1bmN0aW9uKG9wdF9wYXJhbXMsIGluaXRfZGYsIHByaW50X2Jlc3RfbW9kcyA9IDApewogICMgU2VsZWN0IHRoZSBTUDUwMCBhbmQgdGhlIG9wdGltYWwgY29sdW1zbiBmcm9tIGVhcmxpZXIKICBzbWFsbF9kZj0gaW5pdF9kZlssYygxLG9wdF9wYXJhbXMrMSldCiAgIyBQcmludCB0aGUgb3B0aW1hbCBwYXJhbWV0ZXJzCiAgaWYgKHByaW50X2Jlc3RfbW9kcyAhPSAwKXsKICAgIHByaW50KHBhc3RlMCgiVGhlIGJlc3QgbXVsdGl2YXJpYXRlIENBVmlhUiBtb2RlbCBmb3IgdGhlIHRpbWUgcGVyaW9kIGZyb20gIiwKICAgICAgICAgICAgICAgICAgbWluKGluZGV4KHNtYWxsX2RmKSksICIgdG8gIiwgbWF4KGluZGV4KHNtYWxsX2RmKSksIiBpcyAiLCBjb2xuYW1lcyhzbWFsbF9kZilbMl0sIAogICAgICAgICAgICAgICAgICIgYW5kIHRoZSBiZXN0IHVuaXZhcmlhdGUgQ0FWaWFSIG1vZGVsIGZvciB0aGUgdGltZSBwZXJpb2QgaXMgIiwgY29sbmFtZXMoc21hbGxfZGYpWzNdKSkKICB9CiAgIyBSZXR1cm4gdGhlIGRhdGEgZnJhbWUKICByZXR1cm4oc21hbGxfZGYpCn0KCnNtYWxsX2RmMSA9IHNtYWxsX2RmX2ZuKGJlc3QsIGRhdDEkcHJlZHMsIHByaW50X2Jlc3RfbW9kcyA9IDEpCgoKIyB0ZXN0X2RmID0gc21hbGxfZGZfZm4oYmVzdCwgZGF0MSRwcmVkcywgcHJpbnRfYmVzdF9tb2RzID0gMSkKCgoKCmBgYAoKYGBge3J9CiMnIEZpdCBtb2RlbHMgZm9yIHRoZSB1bml2YXJpYXRlIENBVmlhUiBtb2RlbHMKIycKIycgQHBhcmFtIGlucHV0X2RmIC0gdGhlIGlucHV0IGRhdGEgZm9yIHRoZSB1bml2YXJpYXRlIENBVmlhUiBNb2RlbC4gSXQgc2hvdWxkIGJlIGZyb20gdGhlIHNtYWxsX2RmX2ZuIGFib3ZlCiMnCiMnIEByZXR1cm4gLSBhIDJ4NCB0YWJsZSB3aXRoIHRoZSBvcHRpbWFsIHBhcmFtZXRlcnMgZm9yIHNrZXcgbm9ybWFsIGFuZCBHdW1iZWwgYW5kIHRoZSBLLUwgZGl2ZXJnZW5jZSBmb3IgZWFjaAojJyBAZXhwb3J0CiMnCiMnIEBleGFtcGxlcyAtIHV2X2Nhdl9maXQoc21hbGxfZGYxKQp1dl9jYXZfZml0ID0gZnVuY3Rpb24oaW5wdXRfZGYpewogICMgRml0IHNrZXcgbm9ybWFsCiAgc25fcGFyYW0gPSBzbm9ybUZpdChpbnB1dF9kZlssM10pCiAgIyBGaXQgR3VtYmVsCiAgZ3VtX3BhcmFtID0gZ3VtLmZpdChpbnB1dF9kZlssM10sIHNob3cgPSBGQUxTRSkKICAjIEFzc2lnbiB0byBhIGRhdGEgZnJhbWUKICBzbl9wYXJhbV9kZiA9IGFzLmRhdGEuZnJhbWUodChzbl9wYXJhbSRwYXIpKQogIGd1bV9wYXJhbV9kZiA9IGFzLmRhdGEuZnJhbWUodChjKGd1bV9wYXJhbSRtbGUsTkEpKSkKICAjIEFzc2lnbiBjb2x1bW4gbmFtZXMKICBjb2xuYW1lcyhzbl9wYXJhbV9kZikgPC0gYygiTG9jYXRpb24iLCAiU2NhbGUiLCAiU2hhcGUiKQogIGNvbG5hbWVzKGd1bV9wYXJhbV9kZikgPC0gYygiTG9jYXRpb24iLCAiU2NhbGUiLCAiU2hhcGUiKQogICMgUGxvdCB0aGUgZGF0YQogIGggPSBoaXN0KGlucHV0X2RmWywzXSwgYnJlYWtzID0gMjUsIHhsYWIgPSAiTW9kZWxlZCBWYWx1ZXMiLCBtYWluID0gIlVuaXZhcmlhdGUgQ0FWaWFSIikKICAjIE92ZXJzZXQgYSBkZW5zaXR5IGZ1bmN0aW9uIC0gU2tldyBOb3JtYWwKICB4Zml0PC1zZXEobWluKGlucHV0X2RmWywzXSksbWF4KGlucHV0X2RmWywzXSksbGVuZ3RoPTI1MCkKICB5Zml0ID0gZHNub3JtKHhmaXQsIG1lYW4gPSBzbl9wYXJhbSRwYXJbMV0sIHNkID0gc25fcGFyYW0kcGFyWzJdLCB4aSA9IHNuX3BhcmFtJHBhclszXSkKICB5Zml0IDwtIHlmaXQqZGlmZihoJG1pZHNbMToyXSkqbGVuZ3RoKHNtYWxsX2RmWywzXSkKICBsaW5lcyh4Zml0LCB5Zml0LCBjb2w9ImJsdWUiLCBsd2Q9MikKICAjIE92ZXJzZXQgYSBkZW5zaXR5IGZ1bmN0aW9uIC0gR3VtYmVsCiAgeGZpdDwtc2VxKG1pbihpbnB1dF9kZlssM10pLG1heChpbnB1dF9kZlssM10pLGxlbmd0aD0yNTApCiAgeWZpdCA9IGRndW1iZWwoeGZpdCwgbG9jID0gZ3VtX3BhcmFtJG1sZVsxXSwgc2NhbGUgPSBndW1fcGFyYW0kbWxlWzJdKQogIHlmaXQgPC0geWZpdCpkaWZmKGgkbWlkc1sxOjJdKSpsZW5ndGgoc21hbGxfZGZbLDNdKQogIGxpbmVzKHhmaXQsIHlmaXQsIGNvbD0icmVkIiwgbHdkPTIpCiAgIyBPdmVyc2V0IGEgZGVuc2l0eSBmdW5jdGlvbiAtIEdFVgogICMgeGZpdDwtc2VxKG1pbihzbWFsbF9kZlssM10pLG1heChzbWFsbF9kZlssM10pLGxlbmd0aD0yNTApCiAgIyB5Zml0ID0gZGdldih4Zml0LCBsb2MgPSBnZXZfcGFyYW0kbWxlWzFdLCBzY2FsZSA9IGdldl9wYXJhbSRtbGVbMl0sIHNoYXBlID0gZ2V2X3BhcmFtJG1sZVszXSkKICAjIHlmaXQgPC0geWZpdCpkaWZmKGgkbWlkc1sxOjJdKSpsZW5ndGgoc21hbGxfZGZbLDNdKQogICMgbGluZXMoeGZpdCwgeWZpdCwgY29sPSJncmVlbiIsIGx3ZD0yKQogICMgQWRkIGEgbGVnZW5kCiAgbGVnZW5kKCJ0b3BsZWZ0IiwgbGVnZW5kID0gYygiU2tldyBOb3JtYWwiLCAiR3VtYmVsIiksIGNvbCA9IGMoImJsdWUiLCAicmVkIiksIGx0eSA9IGMoMSwxKSwgbHdkID0gYygyLDIpKQogICMgQ29tYmluZSBhbGwgb2YgdGhlIGV4dHJlbWUgdmFsdWUgZGlzdHJpYnV0aW9ucyB0b2dldGhlcgogIGV2X3BhcmFtX2RmID0gYXMuZGF0YS5mcmFtZShyYmluZChzbl9wYXJhbV9kZiwgZ3VtX3BhcmFtX2RmKSkKICByb3duYW1lcyhldl9wYXJhbV9kZikgPC0gYygiU2tldyBOb3JtYWwiLCAiR3VtYmVsIikKICBjb2xuYW1lcyhldl9wYXJhbV9kZikgPC0gYygiTG9jYXRpb24iLCAiU2NhbGUiLCAiU2hhcGUiKQogICMgIyBEaXNwbGF5IGEgcHJldHR5IHRhYmxlCiAgcHJpbnQoZXZfcGFyYW1fZGYgJT4lIGthYmxlKGNhcHRpb24gPSAiT3B0aW1hbCBQYXJhbWV0ZXJzIGZvciB0aGUgQ2FuZGlkYXRlIERpc3RyaWJ1dGlvbnMiLCBkaWdpdHMgPSAzKSAlPiUga2FibGVfc3R5bGluZygic3RyaXBlZCIsIGZ1bGxfd2lkdGggPSBGKSAlPiUga2FibGVfc3R5bGluZygpICU+JSBmb290bm90ZShnZW5lcmFsID0gIkVzdGltYXRlZCBVc2luZyBNYXhpbXVtIExpa2VsaWhvb2QiKSkKICAjIENvbXB1dGUgdGhlIEstTCBkaXZlcmdlbmNlcwogICMgRmlyc3QsIGZpbmQgdGhlIGRlbnNpdHkgb2YgdGhlIGRhdGEKICBkZW5fb2JqID0gaGlzdChzbWFsbF9kZlssM10sIGJyZWFrcyA9IDI1LCBwbG90ID0gRkFMU0UpCiAgIyBSZXdyaXRlIG0yIGFzIHRoZSBvcHRpbWFsIHBhcmFtZXRlcnMgb2Ygc2tldyBub3JtYWwKICAjIE5leHQgY29tcHV0ZSB0aGUgcHJvYmFiaWxpdHkgYXQgZWFjaCBwb2ludCBmb3IgdGhlIGZpdHRlZCBtb2RlbHMKICAjIyBTa2V3LW5vcm1hbAogIHNrbl9kZW4gPSBkc25vcm0oZGVuX29iaiRtaWRzLCBtZWFuID0gbTIkcGFyWzFdLCBzZCA9IG0yJHBhclsyXSwgeGkgPSBtMiRwYXJbM10pCiAgIyMgR3VtYmVsCiAgZ3VtYl9kZW4gPSBkZ3VtYmVsKGRlbl9vYmokbWlkcywgbG9jID0gZ3VtX3BhcmFtJG1sZVsxXSwgc2NhbGUgPSBndW1fcGFyYW0kbWxlWzJdKQogICMjIEdFVgogICMgZ2V2X2RlbiA9IGRnZXYoZGVuX29iaiRtaWRzLCBsb2MgPSBnZXZfcGFyYW0kbWxlWzFdLCBzY2FsZSA9IGdldl9wYXJhbSRtbGVbMl0sIHNoYXBlID0gZ2V2X3BhcmFtJG1sZVszXSkKICAjIENhbGN1bGF0ZSB0aGUgSy1MIGRpdmVyZ2VuY2VzIGZvciBlYWNoCiAga2xfc2tuID0gS0xEKGRlbl9vYmokZGVuc2l0eSwgc2tuX2RlbikKICBrbF9ndW1iID0gS0xEKGRlbl9vYmokZGVuc2l0eSwgZ3VtYl9kZW4pCiAgIyBrbF9nZXYgPSBLTEQobTNfZGVuJGRlbnNpdHksIGdldl9kZW4pCiAgIyBDb21iaW5lIGludG8gYSBkYXRhIGZyYW1lCiAga2xfZGYgPSBhcy5kYXRhLmZyYW1lKGNiaW5kKGtsX3NrbiRtZWFuLnN1bS5LTEQsIGtsX2d1bWIkbWVhbi5zdW0uS0xEKSkKICByb3duYW1lcyhrbF9kZikgPC0gYygiTWVhbiBTdW0gSy1MIERpdmVyZ2VuY2UiKQogIGNvbG5hbWVzKGtsX2RmKSA8LSBjKCJTa2V3LU5vcm1hbCIsICJHdW1iZWwiKQogICMgRGlzcGxheSBhIHByZXR0eSB0YWJsZQogIHByaW50KGtsX2RmICU+JSBrYWJsZShjYXB0aW9uID0gIkNvbXBhcmluZyBLLUwgRGl2ZXJnZW5jZXMgQnkgTW9kZWwgRml0cyIsIGRpZ2l0cyA9IDIpICU+JSBrYWJsZV9zdHlsaW5nKCJzdHJpcGVkIiwgZnVsbF93aWR0aCA9IEYpICU+JSBrYWJsZV9zdHlsaW5nKCkpCiAgIyBDcmVhdGUgYSBmaW5hbCBvdXRwdXQgZGF0YWZyYW1lCiAgb3V0cHV0X2RmID0gYXMuZGF0YS5mcmFtZShjYmluZChldl9wYXJhbV9kZiwgdChrbF9kZikpKQogICMgUmVuYW1lIHRoZSBsYXN0bmFtZQogIGNvbG5hbWVzKG91dHB1dF9kZilbNF0gPC0gYygiSy1MIERpdmVyZ2VuY2UiKSAKICAjIFJldHVybiB0aGUgb3B0aW1hbCBkYXRhCiAgcmV0dXJuKG91dHB1dF9kZikKfQoKYWJjID0gdXZfY2F2X2ZpdChzbWFsbF9kZjEpCiMgc21hbGxfZGYxCiMgYWJjCgoKYGBgCgpgYGB7cn0KIycgRml0IG1vZGVscyBmb3IgdGhlIHVuaXZhcmlhdGUgQ0FWaWFSIG1vZGVscwojJwojJyBAcGFyYW0gaW5wdXRfZGYgLSB0aGUgaW5wdXQgZGF0YSBmb3IgdGhlIG11bHRpdmFyaWF0ZSBDQVZpYVIgTW9kZWwuIEl0IHNob3VsZCBiZSBmcm9tIHRoZSBzbWFsbF9kZl9mbiBhYm92ZQojJwojJyBAcmV0dXJuIC0gYSAyeDQgdGFibGUgd2l0aCB0aGUgb3B0aW1hbCBwYXJhbWV0ZXJzIGZvciBza2V3IG5vcm1hbCBhbmQgR3VtYmVsIGFuZCB0aGUgSy1MIGRpdmVyZ2VuY2UgZm9yIGVhY2gKIycgQGV4cG9ydAojJwojJyBAZXhhbXBsZXMgLSB1dl9jYXZfZml0KHNtYWxsX2RmMSkKbXZfY2F2X2ZpdCA9IGZ1bmN0aW9uKGlucHV0X2RmKXsKICAjIEVzdGltYXRlIHRoZSBtbGUgb2YgdGhlIFNECiAgbWVhbl9tbGUgPSBtZWFuKGlucHV0X2RmWywyXSkKICBzZF9tbGUgPSAoc3VtKChpbnB1dF9kZlssMl0gLSBtZWFuX21sZSleMikvbGVuZ3RoKGlucHV0X2RmWywyXSkpXigxLzIpCiAgIyBGaXQgYSBub3JtYWwKICBub3JtX3BhcmFtID0gYyhtZWFuX21sZSwgc2RfbWxlKQogICMgRml0IHNrZXcgbm9ybWFsCiAgc25fcGFyYW0gPSBzbm9ybUZpdChpbnB1dF9kZlssMl0pCiAgIyBBc3NpZ24gdG8gYSBkYXRhIGZyYW1lCiAgbm9ybV9wYXJhbV9kZiA9IGFzLmRhdGEuZnJhbWUodChjKG5vcm1fcGFyYW0sTkEpKSkKICBzbl9wYXJhbV9kZiA9IGFzLmRhdGEuZnJhbWUodChzbl9wYXJhbSRwYXIpKQogICMgQXNzaWduIGNvbHVtbiBuYW1lcwogIGNvbG5hbWVzKG5vcm1fcGFyYW1fZGYpIDwtIGMoIkxvY2F0aW9uIiwgIlNjYWxlIiwgIlNoYXBlIikKICBjb2xuYW1lcyhzbl9wYXJhbV9kZikgPC0gYygiTG9jYXRpb24iLCAiU2NhbGUiLCAiU2hhcGUiKQogICMgUGxvdCB0aGUgZGF0YQogIGggPSBoaXN0KGlucHV0X2RmWywyXSwgYnJlYWtzID0gMjUsIHhsYWIgPSAiTW9kZWxlZCBWYWx1ZXMiLCBtYWluID0gIk11bHRpdmFyaWF0ZSBDQVZpYVIiKQogICMgT3ZlcnNldCBhIGRlbnNpdHkgZnVuY3Rpb24gLSBOb3JtYWwKICB4Zml0PC1zZXEobWluKGlucHV0X2RmWywyXSksbWF4KGlucHV0X2RmWywyXSksbGVuZ3RoPTI1MCkKICB5Zml0ID0gZG5vcm0oeGZpdCwgbWVhbiA9IG5vcm1fcGFyYW1bMV0sIHNkID0gbm9ybV9wYXJhbVsyXSkKICB5Zml0IDwtIHlmaXQqZGlmZihoJG1pZHNbMToyXSkqbGVuZ3RoKHNtYWxsX2RmWywyXSkKICBsaW5lcyh4Zml0LCB5Zml0LCBjb2w9InJlZCIsIGx3ZD0yKQogICMgT3ZlcnNldCBhIGRlbnNpdHkgZnVuY3Rpb24gLSBTa2V3IE5vcm1hbAogIHhmaXQ8LXNlcShtaW4oaW5wdXRfZGZbLDJdKSxtYXgoaW5wdXRfZGZbLDJdKSxsZW5ndGg9MjUwKQogIHlmaXQgPSBkc25vcm0oeGZpdCwgbWVhbiA9IHNuX3BhcmFtJHBhclsxXSwgc2QgPSBzbl9wYXJhbSRwYXJbMl0sIHhpID0gc25fcGFyYW0kcGFyWzNdKQogIHlmaXQgPC0geWZpdCpkaWZmKGgkbWlkc1sxOjJdKSpsZW5ndGgoc21hbGxfZGZbLDJdKQogIGxpbmVzKHhmaXQsIHlmaXQsIGNvbD0iYmx1ZSIsIGx3ZD0yKQogICMgT3ZlcnNldCBhIGRlbnNpdHkgZnVuY3Rpb24gLSBHRVYKICAjIHhmaXQ8LXNlcShtaW4oc21hbGxfZGZbLDNdKSxtYXgoc21hbGxfZGZbLDNdKSxsZW5ndGg9MjUwKQogICMgeWZpdCA9IGRnZXYoeGZpdCwgbG9jID0gZ2V2X3BhcmFtJG1sZVsxXSwgc2NhbGUgPSBnZXZfcGFyYW0kbWxlWzJdLCBzaGFwZSA9IGdldl9wYXJhbSRtbGVbM10pCiAgIyB5Zml0IDwtIHlmaXQqZGlmZihoJG1pZHNbMToyXSkqbGVuZ3RoKHNtYWxsX2RmWywzXSkKICAjIGxpbmVzKHhmaXQsIHlmaXQsIGNvbD0iZ3JlZW4iLCBsd2Q9MikKICAjIEFkZCBhIGxlZ2VuZAogIGxlZ2VuZCgidG9wbGVmdCIsIGxlZ2VuZCA9IGMoIk5vcm1hbCIsICJTa2V3IE5vcm1hbCIpLCBjb2wgPSBjKCJibHVlIiwgInJlZCIpLCBsdHkgPSBjKDEsMSksIGx3ZCA9IGMoMiwyKSkKICAjIENvbWJpbmUgYWxsIG9mIHRoZSBleHRyZW1lIHZhbHVlIGRpc3RyaWJ1dGlvbnMgdG9nZXRoZXIKICBldl9wYXJhbV9kZiA9IGFzLmRhdGEuZnJhbWUocmJpbmQobm9ybV9wYXJhbV9kZiwgc25fcGFyYW1fZGYpKQogIHJvd25hbWVzKGV2X3BhcmFtX2RmKSA8LSBjKCJOb3JtYWwiLCAiU2tldyBOb3JtYWwiKQogIGNvbG5hbWVzKGV2X3BhcmFtX2RmKSA8LSBjKCJMb2NhdGlvbiIsICJTY2FsZSIsICJTaGFwZSIpCiAgIyAjIERpc3BsYXkgYSBwcmV0dHkgdGFibGUKICBwcmludChldl9wYXJhbV9kZiAlPiUga2FibGUoY2FwdGlvbiA9ICJPcHRpbWFsIFBhcmFtZXRlcnMgZm9yIHRoZSBDYW5kaWRhdGUgRGlzdHJpYnV0aW9ucyIsIGRpZ2l0cyA9IDMpICU+JSBrYWJsZV9zdHlsaW5nKCJzdHJpcGVkIiwgZnVsbF93aWR0aCA9IEYpICU+JSBrYWJsZV9zdHlsaW5nKCkgJT4lIGZvb3Rub3RlKGdlbmVyYWwgPSAiRXN0aW1hdGVkIFVzaW5nIE1heGltdW0gTGlrZWxpaG9vZCIpKQogICMgQ29tcHV0ZSB0aGUgSy1MIGRpdmVyZ2VuY2VzCiAgIyBGaXJzdCwgZmluZCB0aGUgZGVuc2l0eSBvZiB0aGUgZGF0YQogIGRlbl9vYmogPSBoaXN0KHNtYWxsX2RmWywyXSwgYnJlYWtzID0gMjUsIHBsb3QgPSBGQUxTRSkKICAjIFJld3JpdGUgbTIgYXMgdGhlIG9wdGltYWwgcGFyYW1ldGVycyBvZiBza2V3IG5vcm1hbAogICMgTmV4dCBjb21wdXRlIHRoZSBwcm9iYWJpbGl0eSBhdCBlYWNoIHBvaW50IGZvciB0aGUgZml0dGVkIG1vZGVscwogICMjIFNrZXctbm9ybWFsCiAgbm9ybV9kZW4gPSBkbm9ybShkZW5fb2JqJG1pZHMsIG1lYW4gPSBub3JtX3BhcmFtWzFdLCBzZCA9IG5vcm1fcGFyYW1bMl0pCiAgIyMgR3VtYmVsCiAgIyBndW1iX2RlbiA9IGRndW1iZWwoZGVuX29iaiRtaWRzLCBsb2MgPSBndW1fcGFyYW0kbWxlWzFdLCBzY2FsZSA9IGd1bV9wYXJhbSRtbGVbMl0pCiAgc2tuX2RlbiA9IGRzbm9ybShkZW5fb2JqJG1pZHMsIG1lYW4gPSBtMiRwYXJbMV0sIHNkID0gbTIkcGFyWzJdLCB4aSA9IG0yJHBhclszXSkKICAjIyBHRVYKICAjIGdldl9kZW4gPSBkZ2V2KGRlbl9vYmokbWlkcywgbG9jID0gZ2V2X3BhcmFtJG1sZVsxXSwgc2NhbGUgPSBnZXZfcGFyYW0kbWxlWzJdLCBzaGFwZSA9IGdldl9wYXJhbSRtbGVbM10pCiAgIyBDYWxjdWxhdGUgdGhlIEstTCBkaXZlcmdlbmNlcyBmb3IgZWFjaAogIGtsX25vcm0gPSBLTEQoZGVuX29iaiRkZW5zaXR5LCBub3JtX2RlbikKICBrbF9za24gPSBLTEQoZGVuX29iaiRkZW5zaXR5LCBza25fZGVuKQogICMga2xfZ2V2ID0gS0xEKG0zX2RlbiRkZW5zaXR5LCBnZXZfZGVuKQogICMgQ29tYmluZSBpbnRvIGEgZGF0YSBmcmFtZQogIGtsX2RmID0gYXMuZGF0YS5mcmFtZShjYmluZChrbF9ub3JtJG1lYW4uc3VtLktMRCwga2xfc2tuJG1lYW4uc3VtLktMRCkpCiAgcm93bmFtZXMoa2xfZGYpIDwtIGMoIk1lYW4gU3VtIEstTCBEaXZlcmdlbmNlIikKICBjb2xuYW1lcyhrbF9kZikgPC0gYygiTm9ybWFsIiwgIlNrZXctTm9ybWFsIikKICAjIERpc3BsYXkgYSBwcmV0dHkgdGFibGUKICBwcmludChrbF9kZiAlPiUga2FibGUoY2FwdGlvbiA9ICJDb21wYXJpbmcgSy1MIERpdmVyZ2VuY2VzIEJ5IE1vZGVsIEZpdHMiLCBkaWdpdHMgPSAyKSAlPiUga2FibGVfc3R5bGluZygic3RyaXBlZCIsIGZ1bGxfd2lkdGggPSBGKSAlPiUga2FibGVfc3R5bGluZygpKQogICMgQ3JlYXRlIGEgZmluYWwgb3V0cHV0IGRhdGFmcmFtZQogIG91dHB1dF9kZiA9IGFzLmRhdGEuZnJhbWUoY2JpbmQoZXZfcGFyYW1fZGYsIHQoa2xfZGYpKSkKICAjIFJlbmFtZSB0aGUgbGFzdG5hbWUKICBjb2xuYW1lcyhvdXRwdXRfZGYpWzRdIDwtIGMoIkstTCBEaXZlcmdlbmNlIikgCiAgIyBSZXR1cm4gdGhlIG9wdGltYWwgZGF0YQogIHJldHVybihvdXRwdXRfZGYpCn0KCmRlZiA9IG12X2Nhdl9maXQoc21hbGxfZGYxKQpzbWFsbF9kZjFbLDJdCgphYmMKZGVmCgoKYGBgCgpgYGB7cn0Kb3B0X3BhcmFtX2RmCmBgYAoKCiMgTUFTVEVSIEZVTkNUSU9OCgpgYGB7cn0KIycgVGhpcyBpcyB0aGUgbWFzdGVyIGZ1bmN0aW9uIHRoYXQgcnVucyBldmVyeXRoaW5nCiMnCiMnIEBwYXJhbSB2YXJfbGV2ZWwgLSB0aGUgVmFSIGxldmVsIHVzZWQgdG8gcHVsbCBpbiB0aGVlc2lzIGRhdGEKIycgQHBhcmFtIHllYXIgLSB0aGUgeWVhciBvZiB0aGVzaXMgZGF0YSB0byBwdWxsIGluCiMnIEBwYXJhbSB0X3Byb2IgLSB0aGUgcHJvYmFiaWxpdHkgb2YgdHJhbnNpdGlvbgojJyBAcGFyYW0gcHJpb3JfcHJvYiAtIHRoZSBwcmlvciBwcm9iYWJpbGl0eQojJyBAcGFyYW0gaXJyX2Rpc3QgLSB0aGUgaXJyYXRpb25hbCBkaXN0cmlidXRpb24uIFRoZSBkZWZhdWx0IGlzIEd1bm1iZWwKIycgQHBhcmFtIHJhdF9kaXN0IC0gdGhlIHJhdGlvbmFsIGRpc3RyaWJ1dGlvbi4gVGhlIGRlZmF1bHQgaXMgTm9ybWFsCiMnIEBwYXJhbSBwcmludF9iZXN0X21vZHMgLSBkbyB5b3UgcHJpbnQgdGhlIGJlc3QgbW9kZWxzPwojJyBAcGFyYW0gcGF0aCAtIGZpbGVwYXRoIHRvIHdoZXJlIHRoZSBhbGwgRVRGIHJ1bnMgYXJlIHN0b3JlZC4gRG9uJ3QgbW9kaWZ5IHRoaXMgd2l0aG91dCBhIGdvb2QgcmVhc29uLgojJwojJyBAcmV0dXJuIC0gYSBsaXN0IG9mIHRoZSBwcm9iYWJpbGl0aWVzLCB0aGUgYWxwaGFzLCBhbmQgdGhlIGJldGFzCiMnIEBleHBvcnQKIycKIycgQGV4YW1wbGVzIC0gcmVzXzIwMDhfMXBjXzF0cCA9IGhtbV9tYXN0ZXIoMSwgMjAwOCwgdF9wcm9iID0gMC4wMSkKaG1tX21hc3RlciA9IGZ1bmN0aW9uKHZhcl9sZXZlbCwgeWVhciwgdF9wcm9iID0gMC4xLCBwcmlvcl9wcm9iID0gMC41LCBpcnJfZGlzdCA9ICJHdW1iZWwiLCByYXRfZGlzdCA9ICJOb3JtYWwiLAogICAgICAgICAgICAgICAgICAgICAgcHJpbnRfYmVzdF9tb2RzID0gMSwgcGF0aCA9ICIvVXNlcnMvc3RldmVubW9lbi9Eb2N1bWVudHMvR2l0SHViL0NBVmlhUl9NU190aGVzaXMvRGF0YV9FeHBvcnQvU1BZX2FsbF9FVEZfcnVucy8iKXsKICAjIEZpcnN0LCBwdWxsIHRoZSBkYXRhCiAgZGExID0gaW1wb3J0X2RhdCh2YXJfbGV2ZWwgPSB2YXJfbGV2ZWwsIHllYXIgPSB5ZWFyLCBwYXRoID0gcGF0aCkKICAjIFNlY29uZCwgIHBpY2sgdGhlIGJlc3QKICBiZXN0ID0gcGlja19iZXN0KGRhMSRsb3NzZXMpCiAgIyBUaGlyZCwgc3Vic2V0IHRoZSBkYXRhCiAgc21hbGxfZGEgPSBzbWFsbF9kZl9mbihiZXN0LCBkYTEkcHJlZHMsIHByaW50X2Jlc3RfbW9kcyA9IHByaW50X2Jlc3RfbW9kcykKICAjIEZvdXJ0aCwgZmluZCB0aGUgb3B0aW1hbCB1bml2YXJpYXRlIHBhcmFtZXRlcnMgLSB0aGUgaXJyYXRpb25hbCBvbmVzCiAgIyB1dl9jYXZfZml0ID0gZnVuY3Rpb24oaW5wdXRfZGYpewogIG9wdF91dl9wYXJhbSA9IHV2X2Nhdl9maXQoc21hbGxfZGEpCiAgIyBGaWZ0aCwgZmluZCB0aGUgb3B0aW1hbCBtdWx0aXZhcmlhdGUgcGFyYW1ldGVycyAtIHRoZSByYXRpb25hbCBvbmVzCiAgb3B0X212X3BhcmFtID0gbXZfY2F2X2ZpdChzbWFsbF9kYSkKICAjIENvbWJpbmUgYm90aCBpbnRvIGEgbmljZSBsaXR0bGUgdGhpbmcKICAjIE5leHQsIEkgd2lsbCBmZWVkIHRoZXNlIGludG8gdGhlIGhtbV9maXQgZnVuY3Rpb24sIGRlY2lkaW5nIHRvIGNob29zZSB0aGUgcGFyYW1zIGJhc2VkIG9uIEstTCBkaXZlcmdlbmNlCiAgb3V0ID0gaG1tX2ZpdChpbnB1dF9kZiA9IHNtYWxsX2RhLCB0X3Byb2IgPSB0X3Byb2IsIHByaW9yX3Byb2IgPSBwcmlvcl9wcm9iLCBpcnJfZGlzdCA9IGlycl9kaXN0LAogICAgICAgICAgICAgICAgcmF0X2Rpc3QgPSByYXRfZGlzdCwgcmF0X29wdF9wYXJhbSA9IG9wdF9tdl9wYXJhbSwgaXJyX29wdF9wYXJhbSA9IG9wdF91dl9wYXJhbSwgdmFyX2xldmVsID0gdmFyX2xldmVsKQogICMgUmV0dXJuIG91dAogIHJldHVybihvdXQpCiAgIyBobW1fZml0ID0gZnVuY3Rpb24oaW5wdXRfZGYsIHRfcHJvYiwgcHJpb3JfcHJvYiwgaXJyX2Rpc3QgPSAiR3VtYmVsIiwgcmF0X2Rpc3QgPSAiTm9ybWFsIil7CiAgIyBTdG9wcGluZyBwb2ludCBmb3IgMS8xNy8yMDIxCiAgIyBKVU5LCgojICMnIEEgZnVuY3Rpb24gdG8gc3Vic2V0IHRoZSBkYXRhIGFuZCBwcmludCB0aGUgb3B0aW1hbCBtb2RlbHMKIyAjJwojICMnIEBwYXJhbSBvcHRfcGFyYW1zIC0gdGhlIG9wdGltYWwgcGFyYW1ldGVycyBmcm9tIHRoZSBwaWNrX2Jlc3QgZnVuY3Rpb24KIyAjJyBAcGFyYW0gaW5pdF9kZiAtIHRoZSBpbml0aWFsIGRhdGEgZnJhbWUgdG8gcmVhZCBvZmYgb2YKIyAjJyBAcGFyYW0gcHJpbnRfYmVzdF9tb2RzIC0gcHJpbnQgdGhlIGJlc3QgbW9kZWxzIHRoYXQgd2lsbCBnbyB0aHJvdWdoIHRoZSBvcHRpbWl6YXRpb24gcHJvY2VzcwojICMnCiMgIycgQHJldHVybiAtIGEgc3Vic2V0dGVkIGRhdGEgZnJhbWUKIyAjJyBAZXhwb3J0CiMgIycKIyAjJyBAZXhhbXBsZXMgLSB0ZXN0X2RmID0gc21hbGxfZGZfZm4oYmVzdCwgZGF0MSRwcmVkcywgcHJpbnRfYmVzdF9tb2RzID0gMSkKIyBzbWFsbF9kZl9mbiA9IGZ1bmN0aW9uKG9wdF9wYXJhbXMsIGluaXRfZGYsIHByaW50X2Jlc3RfbW9kcyA9IDApewojICAgIyBTZWxlY3QgdGhlIFNQNTAwIGFuZCB0aGUgb3B0aW1hbCBjb2x1bXNuIGZyb20gZWFybGllcgojICAgc21hbGxfZGY9IGluaXRfZGZbLGMoMSxvcHRfcGFyYW1zKzEpXQojICAgIyBQcmludCB0aGUgb3B0aW1hbCBwYXJhbWV0ZXJzCiMgICBpZiAocHJpbnRfYmVzdF9tb2RzICE9IDApewojICAgICBwcmludChwYXN0ZTAoIlRoZSBiZXN0IG11bHRpdmFyaWF0ZSBDQVZpYVIgbW9kZWwgZm9yIHRoZSB0aW1lIHBlcmlvZCBmcm9tICIsCiMgICAgICAgICAgICAgICAgICAgbWluKGluZGV4KHNtYWxsX2RmKSksICIgdG8gIiwgbWF4KGluZGV4KHNtYWxsX2RmKSksIiBpcyAiLCBjb2xuYW1lcyhzbWFsbF9kZilbMl0sIAojICAgICAgICAgICAgICAgICAgIiBhbmQgdGhlIGJlc3QgdW5pdmFyaWF0ZSBDQVZpYVIgbW9kZWwgZm9yIHRoZSB0aW1lIHBlcmlvZCBpcyAiLCBjb2xuYW1lcyhzbWFsbF9kZilbM10pKQojICAgfQojICAgIyBSZXR1cm4gdGhlIGRhdGEgZnJhbWUKIyAgIHJldHVybihzbWFsbF9kZikKIyB9CiMgCiMgc21hbGxfZGYxID0gc21hbGxfZGZfZm4oYmVzdCwgZGF0MSRwcmVkcywgcHJpbnRfYmVzdF9tb2RzID0gMSkKICAKICAjIGltcG9ydF9kYXQgPSBmdW5jdGlvbih2YXJfbGV2ZWwsIHllYXIsIHBhdGggPSAiL1VzZXJzL3N0ZXZlbm1vZW4vRG9jdW1lbnRzL0dpdEh1Yi9DQVZpYVJfTVNfdGhlc2lzL0RhdGFfRXhwb3J0L1NQWV9hbGxfRVRGX3J1bnMvIil7CiAgIyBobW1fZml0ID0gZnVuY3Rpb24oaW5wdXRfZGYsIHRfcHJvYiwgcHJpb3JfcHJvYiwgaXJyX2Rpc3QgPSAiR3VtYmVsIiwgcmF0X2Rpc3QgPSAiTm9ybWFsIil7CiMgICAjJyBBIGZ1bmN0aW9uIHRoYXQgY2hvb3NlcyB0aGUgb3B0aW1hbCBtb2RlbHMKIyAjJwojICMnIEBwYXJhbSBsb3NzX21hdCAtIGxvc3MgbWF0cml4IGZyb20gcHJldmlvdXMgY29kZQojICMnCiMgIycgQHJldHVybiAtIHRoZSBvcHRpbWFsIG1vZGVscyBmb3IgdGhlIEhNTQojICMnIEBleHBvcnQKIyAjJwojICMnIEBleGFtcGxlcyAtIHBpY2tfYmVzdChkYXQxKQojIHBpY2tfYmVzdCA9IGZ1bmN0aW9uKGxvc3NfbWF0KXsKIyAgICMgRmluZCB0aGUgY29sdW1uIHN1bXMKIyAgIGNzID0gY29sU3Vtcyhsb3NzX21hdCkKIyAgICMgU3Vic2V0IGludG8gdHdvIC0gcmF0aW9uYWwgYW5kIGlycmF0aW9uYWwgcGFydHMgKHNwbGl0IGluIHR3bykKIyAgIHJhdF9zdW0gPSBjc1sxOjRdCiMgICBpcnJfc3VtID0gY3NbNTo4XQojICAgIyBGaW5kIHRoZSBtaW5pbWl6ZXIgb2YgZWFjaCBzZXQKIyAgIHJhdF9taW4gPSB3aGljaC5taW4ocmF0X3N1bSkKIyAgICMgQWRkIDQgZm9yIHRoZSBvZmZzZXQKIyAgIGlycl9taW4gPSB3aGljaC5taW4oaXJyX3N1bSkgKyA0CiMgICAjIHByaW50KGMocmF0X21pbiwgaXJyX21pbikpCiMgICAjIFJldHVybiB0aGUgb3B0aW1hbCBwYWlycwojICAgcmV0dXJuKGMocmF0X21pbiwgaXJyX21pbikpCiMgfQoKIyBiZXN0ID0gcGlja19iZXN0KGRhdDEkbG9zc2VzKQp9CmBgYAoKIyBSRVNVTFRTIEZST00gTUFTVEVSIEZVTkNUSU9OCgojIyAyMDA4CgojIyMgMSUgVFAKCmBgYHtyfQpyZXNfMjAwOF8xcGNfMXRwID0gaG1tX21hc3RlcigxLCAyMDA4LCB0X3Byb2IgPSAwLjAxKQpyZXNfMjAwOF81cGNfMXRwID0gaG1tX21hc3Rlcig1LCAyMDA4LCB0X3Byb2IgPSAwLjAxKQpyZXNfMjAwOF8xMHBjXzF0cCA9IGhtbV9tYXN0ZXIoMTAsIDIwMDgsIHRfcHJvYiA9IDAuMDEpCgojIHJlc18yMDA4XzFwY18xdHAkCmBgYAoKIyMjIDUlIFRQCgpgYGB7cn0KcmVzXzIwMDhfMXBjXzV0cCA9IGhtbV9tYXN0ZXIoMSwgMjAwOCwgdF9wcm9iID0gMC4wNSkKcmVzXzIwMDhfNXBjXzV0cCA9IGhtbV9tYXN0ZXIoNSwgMjAwOCwgdF9wcm9iID0gMC4wNSkKcmVzXzIwMDhfMTBwY181dHAgPSBobW1fbWFzdGVyKDEwLCAyMDA4LCB0X3Byb2IgPSAwLjA1KQpgYGAKCgojIyMgMTAlIFRQCgpgYGB7cn0KcmVzXzIwMDhfMXBjXzEwdHAgPSBobW1fbWFzdGVyKDEsIDIwMDgsIHRfcHJvYiA9IDAuMTApCnJlc18yMDA4XzVwY18xMHRwID0gaG1tX21hc3Rlcig1LCAyMDA4LCB0X3Byb2IgPSAwLjEwKQpyZXNfMjAwOF8xMHBjXzEwdHAgPSBobW1fbWFzdGVyKDEwLCAyMDA4LCB0X3Byb2IgPSAwLjEwKQpgYGAKCiMjIyAyMCUgVFAKCmBgYHtyfQpyZXNfMjAwOF8xcGNfMjB0cCA9IGhtbV9tYXN0ZXIoMSwgMjAwOCwgdF9wcm9iID0gMC4yMCkKcmVzXzIwMDhfNXBjXzIwdHAgPSBobW1fbWFzdGVyKDUsIDIwMDgsIHRfcHJvYiA9IDAuMjApCnJlc18yMDA4XzEwcGNfMjB0cCA9IGhtbV9tYXN0ZXIoMTAsIDIwMDgsIHRfcHJvYiA9IDAuMjApCmBgYAoKIyMjIDMzJSBUUAoKYGBge3J9CnJlc18yMDA4XzFwY18zM3RwID0gaG1tX21hc3RlcigxLCAyMDA4LCB0X3Byb2IgPSAwLjMzKQpyZXNfMjAwOF81cGNfMzN0cCA9IGhtbV9tYXN0ZXIoNSwgMjAwOCwgdF9wcm9iID0gMC4zMykKcmVzXzIwMDhfMTBwY18zM3RwID0gaG1tX21hc3RlcigxMCwgMjAwOCwgdF9wcm9iID0gMC4zMykKYGBgCgojIyAyMDEwCgoKYGBge3J9CnJlc18yMDEwXzFwY18xMHRwID0gaG1tX21hc3RlcigxLCAyMDEwLCB0X3Byb2IgPSAwLjEwKQpyZXNfMjAxMF81cGNfMTB0cCA9IGhtbV9tYXN0ZXIoNSwgMjAxMCwgdF9wcm9iID0gMC4xMCkKcmVzXzIwMTBfMTBwY18xMHRwID0gaG1tX21hc3RlcigxMCwgMjAxMCwgdF9wcm9iID0gMC4xMCkKYGBgCgojIyAyMDE0CgoKYGBge3J9CnJlc18yMDE0XzFwY18xMHRwID0gaG1tX21hc3RlcigxLCAyMDE0LCB0X3Byb2IgPSAwLjEwKQpyZXNfMjAxNF81cGNfMTB0cCA9IGhtbV9tYXN0ZXIoNSwgMjAxNCwgdF9wcm9iID0gMC4xMCkKcmVzXzIwMTRfMTBwY18xMHRwID0gaG1tX21hc3RlcigxMCwgMjAxNCwgdF9wcm9iID0gMC4xMCkKYGBgCgojIyAyMDE2CgoKYGBge3J9CnJlc18yMDE2XzFwY18xMHRwID0gaG1tX21hc3RlcigxLCAyMDE2LCB0X3Byb2IgPSAwLjEwKQpyZXNfMjAxNl81cGNfMTB0cCA9IGhtbV9tYXN0ZXIoNSwgMjAxNiwgdF9wcm9iID0gMC4xMCkKcmVzXzIwMTZfMTBwY18xMHRwID0gaG1tX21hc3RlcigxMCwgMjAxNiwgdF9wcm9iID0gMC4xMCkKYGBgCgoKYGBge3J9CiMgRml0IGEgc2tldyBub3JtYWwKbTEgPSBzbm9ybUZpdChzbWFsbF9kZlssMl0pCm0yID0gc25vcm1GaXQoc21hbGxfZGZbLDNdKQoKIyBtMQoKIyBzbm9ybUZpdChzbWFsbF9kZlssMl0rMSkKIyBzbm9ybUZpdChzbWFsbF9kZlssM10rMSkKIyBUaGVzZSBtYXkgbm90IHdvcmsgdmVyeSB3ZWxsCgojIHNxdWFyZV92YWwgPSBzbWFsbF9kZlssM11eMgojIG0zID0gc25vcm1GaXQoc3F1YXJlX3ZhbCkKIyBtNCA9IHNub3JtRml0KHQzKQojIG00CgoKCiMgaGlzdCgoc21hbGxfZGZbLDNdKV4yLCBicmVha3MgPSAyNSkKYGBgCgoKYGBge3J9CiMgRml0IGEgZ3VtYmVsIGZ1bmN0aW9uCmd1bV9wYXJhbSA9IGd1bS5maXQoc21hbGxfZGZbLDNdLCBzaG93ID0gRkFMU0UpCiMgP2d1bS5maXQKIyBndW1fcGFyYW0kbWxlCgojIFRyeSBmaXR0aW5nIGEgR0VWIGRpc3RyaWJ1dGlvbgpnZXZfcGFyYW0gPSBnZXYuZml0KHNtYWxsX2RmWywzXSwgc2hvdyA9IEZBTFNFKQojIGdldl9wYXJhbSRtbGUKCiMgIyBQbG90IGhpc3RvZ3JhbXMKIyAjIEd1bWJlbAojIGggPSBoaXN0KHNtYWxsX2RmWywzXSwgYnJlYWtzID0gMjUpCiMgIyBPdmVyc2V0IGEgZGVuc2l0eSBmdW5jdGlvbgojIHhmaXQ8LXNlcShtaW4oc21hbGxfZGZbLDNdKSxtYXgoc21hbGxfZGZbLDNdKSxsZW5ndGg9MjUwKQojIHlmaXQgPSBkZ3VtYmVsKHhmaXQsIGxvYyA9IGd1bV9wYXJhbSRtbGVbMV0sIHNjYWxlID0gZ3VtX3BhcmFtJG1sZVsyXSkKIyB5Zml0IDwtIHlmaXQqZGlmZihoJG1pZHNbMToyXSkqbGVuZ3RoKHNtYWxsX2RmWywzXSkKIyBsaW5lcyh4Zml0LCB5Zml0LCBjb2w9ImJsdWUiLCBsd2Q9MikKIyAKIyAjIEdFVgojIGggPSBoaXN0KHNtYWxsX2RmWywzXSwgYnJlYWtzID0gMjUpCiMgIyBPdmVyc2V0IGEgZGVuc2l0eSBmdW5jdGlvbgojIHhmaXQ8LXNlcShtaW4oc21hbGxfZGZbLDNdKSxtYXgoc21hbGxfZGZbLDNdKSxsZW5ndGg9MjUwKQojIHlmaXQgPSBkZ2V2KHhmaXQsIGxvYyA9IGdldl9wYXJhbSRtbGVbMV0sIHNjYWxlID0gZ2V2X3BhcmFtJG1sZVsyXSwgc2hhcGUgPSBnZXZfcGFyYW0kbWxlWzNdKQojIHlmaXQgPC0geWZpdCpkaWZmKGgkbWlkc1sxOjJdKSpsZW5ndGgoc21hbGxfZGZbLDNdKQojIGxpbmVzKHhmaXQsIHlmaXQsIGNvbD0iYmx1ZSIsIGx3ZD0yKQoKcGFyKG1mcm93ID0gYygxLDIpKQoKIyBMZXQncyBsb29rIGF0IHRoZSBkYXRhCmggPSBoaXN0KHNtYWxsX2RmWywyXSwgYnJlYWtzID0gMjUsIHhsYWIgPSAiTW9kZWxlZCBWYWx1ZXMiLCBtYWluID0gIk11bHRpdmFyaWF0ZSBDQVZpYVIiKQojIE92ZXJzZXQgYSBkZW5zaXR5IGZ1bmN0aW9uCnhmaXQ8LXNlcShtaW4oc21hbGxfZGZbLDJdKSxtYXgoc21hbGxfZGZbLDJdKSxsZW5ndGg9MjUwKQp5Zml0ID0gZHNub3JtKHhmaXQsIG1lYW4gPSBtMSRwYXJbMV0sIHNkID0gbTEkcGFyWzJdLCB4aSA9IG0xJHBhclszXSkKeWZpdCA8LSB5Zml0KmRpZmYoaCRtaWRzWzE6Ml0pKmxlbmd0aChzbWFsbF9kZlssMl0pCmxpbmVzKHhmaXQsIHlmaXQsIGNvbD0iYmx1ZSIsIGx3ZD0yKQojIE92ZXJzZXQgYSBub3JtYWwgZGVuc2l0eSBmdW5jdGlvbgp4Zml0PC1zZXEobWluKHNtYWxsX2RmWywyXSksbWF4KHNtYWxsX2RmWywyXSksbGVuZ3RoPTI1MCkKeWZpdF9uID0gZG5vcm0oeGZpdCwgbWVhbiA9IG1lYW4oc21hbGxfZGZbLDJdKSwgc2QgPSBzZChzbWFsbF9kZlssMl0pKQp5Zml0X24gPC0geWZpdF9uKmRpZmYoaCRtaWRzWzE6Ml0pKmxlbmd0aChzbWFsbF9kZlssMl0pCmxpbmVzKHhmaXQsIHlmaXRfbiwgY29sPSJyZWQiLCBsd2Q9MiwgbHR5ID0gMikKCiMgQWRkIGEgbGVnZW5kCmxlZ2VuZCgidG9wbGVmdCIsIGxlZ2VuZCA9IGMoIk5vcm1hbCIsICJTa2V3IE5vcm1hbCIpLCBjb2wgPSBjKCJibHVlIiwgInJlZCIpLCBsdHkgPSBjKDEsMiksIGx3ZCA9IGMoMiwyKSkKCgoKIyBMZXQncyBsb29rIGF0IHRoZSBzZWNvbmQgc2V0IG9mIGRhdGEKaCA9IGhpc3Qoc21hbGxfZGZbLDNdLCBicmVha3MgPSAyNSwgeGxhYiA9ICJNb2RlbGVkIFZhbHVlcyIsIG1haW4gPSAiVW5pdmFyaWF0ZSBDQVZpYVIiKQojIE92ZXJzZXQgYSBkZW5zaXR5IGZ1bmN0aW9uIC0gU2tldyBOb3JtYWwKeGZpdDwtc2VxKG1pbihzbWFsbF9kZlssM10pLG1heChzbWFsbF9kZlssM10pLGxlbmd0aD0yNTApCnlmaXQgPSBkc25vcm0oeGZpdCwgbWVhbiA9IG0yJHBhclsxXSwgc2QgPSBtMiRwYXJbMl0sIHhpID0gbTIkcGFyWzNdKQp5Zml0IDwtIHlmaXQqZGlmZihoJG1pZHNbMToyXSkqbGVuZ3RoKHNtYWxsX2RmWywzXSkKbGluZXMoeGZpdCwgeWZpdCwgY29sPSJibHVlIiwgbHdkPTIpCiMgT3ZlcnNldCBhIGRlbnNpdHkgZnVuY3Rpb24gLSBHdW1iZWwKeGZpdDwtc2VxKG1pbihzbWFsbF9kZlssM10pLG1heChzbWFsbF9kZlssM10pLGxlbmd0aD0yNTApCnlmaXQgPSBkZ3VtYmVsKHhmaXQsIGxvYyA9IGd1bV9wYXJhbSRtbGVbMV0sIHNjYWxlID0gZ3VtX3BhcmFtJG1sZVsyXSkKeWZpdCA8LSB5Zml0KmRpZmYoaCRtaWRzWzE6Ml0pKmxlbmd0aChzbWFsbF9kZlssM10pCmxpbmVzKHhmaXQsIHlmaXQsIGNvbD0icmVkIiwgbHdkPTIpCiMgT3ZlcnNldCBhIGRlbnNpdHkgZnVuY3Rpb24gLSBHRVYKeGZpdDwtc2VxKG1pbihzbWFsbF9kZlssM10pLG1heChzbWFsbF9kZlssM10pLGxlbmd0aD0yNTApCnlmaXQgPSBkZ2V2KHhmaXQsIGxvYyA9IGdldl9wYXJhbSRtbGVbMV0sIHNjYWxlID0gZ2V2X3BhcmFtJG1sZVsyXSwgc2hhcGUgPSBnZXZfcGFyYW0kbWxlWzNdKQp5Zml0IDwtIHlmaXQqZGlmZihoJG1pZHNbMToyXSkqbGVuZ3RoKHNtYWxsX2RmWywzXSkKbGluZXMoeGZpdCwgeWZpdCwgY29sPSJncmVlbiIsIGx3ZD0yKQoKIyBBZGQgYSBsZWdlbmQKbGVnZW5kKCJ0b3BsZWZ0IiwgbGVnZW5kID0gYygiU2tldyBOb3JtYWwiLCAiR3VtYmVsIiwgIkdFViIpLCBjb2wgPSBjKCJibHVlIiwgInJlZCIsICJncmVlbiIpLCBsdHkgPSBjKDEsMSwxKSwgbHdkID0gYygyLDIsMikpCgojIHBhcihtZnJvdyA9IGMoMSwzKSkKIyAKIyAjIExldCdzIGxvb2sgYXQgdGhlIGRhdGEKIyBoID0gaGlzdChzbWFsbF9kZlssMl0sIGJyZWFrcyA9IDI1KQojICMgT3ZlcnNldCBhIGRlbnNpdHkgZnVuY3Rpb24KIyB4Zml0PC1zZXEobWluKHNtYWxsX2RmWywyXSksbWF4KHNtYWxsX2RmWywyXSksbGVuZ3RoPTI1MCkKIyB5Zml0ID0gZHNub3JtKHhmaXQsIG1lYW4gPSBtMSRwYXJbMV0sIHNkID0gbTEkcGFyWzJdLCB4aSA9IG0xJHBhclszXSkKIyB5Zml0IDwtIHlmaXQqZGlmZihoJG1pZHNbMToyXSkqbGVuZ3RoKHNtYWxsX2RmWywyXSkKIyBsaW5lcyh4Zml0LCB5Zml0LCBjb2w9ImJsdWUiLCBsd2Q9MikKIyAjIE92ZXJzZXQgYSBub3JtYWwgZGVuc2l0eSBmdW5jdGlvbgojIHhmaXQ8LXNlcShtaW4oc21hbGxfZGZbLDJdKSxtYXgoc21hbGxfZGZbLDJdKSxsZW5ndGg9MjUwKQojIHlmaXRfbiA9IGRub3JtKHhmaXQsIG1lYW4gPSBtZWFuKHNtYWxsX2RmWywyXSksIHNkID0gc2Qoc21hbGxfZGZbLDJdKSkKIyB5Zml0X24gPC0geWZpdF9uKmRpZmYoaCRtaWRzWzE6Ml0pKmxlbmd0aChzbWFsbF9kZlssMl0pCiMgbGluZXMoeGZpdCwgeWZpdF9uLCBjb2w9InJlZCIsIGx3ZD0yLCBsdHkgPSAyKQojIAojICMgTGV0J3MgbG9vayBhdCB0aGUgc2Vjb25kIHNldCBvZiBkYXRhCiMgaCA9IGhpc3Qoc21hbGxfZGZbLDNdLCBicmVha3MgPSAyNSkKIyAjIE92ZXJzZXQgYSBkZW5zaXR5IGZ1bmN0aW9uCiMgeGZpdDwtc2VxKG1pbihzbWFsbF9kZlssM10pLG1heChzbWFsbF9kZlssM10pLGxlbmd0aD0yNTApCiMgeWZpdCA9IGRzbm9ybSh4Zml0LCBtZWFuID0gbTIkcGFyWzFdLCBzZCA9IG0yJHBhclsyXSwgeGkgPSBtMiRwYXJbM10pCiMgeWZpdCA8LSB5Zml0KmRpZmYoaCRtaWRzWzE6Ml0pKmxlbmd0aChzbWFsbF9kZlssM10pCiMgbGluZXMoeGZpdCwgeWZpdCwgY29sPSJibHVlIiwgbHdkPTIpCiMgCiMgIyAjIExldCdzIGxvb2sgYXQgdGhlIHNlY29uZCBzZXQgb2YgZGF0YQojICMgaCA9IGhpc3Qoc3F1YXJlX3ZhbCwgYnJlYWtzID0gMjUpCiMgIyAjIE92ZXJzZXQgYSBkZW5zaXR5IGZ1bmN0aW9uCiMgIyB4Zml0PC1zZXEobWluKHNxdWFyZV92YWwpLG1heChzcXVhcmVfdmFsKSxsZW5ndGg9MjUwKQojICMgeWZpdCA9IGRzbm9ybSh4Zml0LCBtZWFuID0gbTMkcGFyWzFdLCBzZCA9IG0zJHBhclsyXSwgeGkgPSBtMyRwYXJbM10pCiMgIyB5Zml0IDwtIHlmaXQqZGlmZihoJG1pZHNbMToyXSkqbGVuZ3RoKHNxdWFyZV92YWwpCiMgIyBsaW5lcyh4Zml0LCB5Zml0LCBjb2w9ImJsdWUiLCBsd2Q9MikKIyAKIyAjIExldCdzIGxvb2sgYXQgdGhlIHNlY29uZCBzZXQgb2YgZGF0YQojIGggPSBoaXN0KHQzLCBicmVha3MgPSAyNSkKIyAjIE92ZXJzZXQgYSBkZW5zaXR5IGZ1bmN0aW9uCiMgeGZpdDwtc2VxKG1pbih0MyksbWF4KHQzKSxsZW5ndGg9MjUwKQojIHlmaXQgPSBkc25vcm0oeGZpdCwgbWVhbiA9IG00JHBhclsxXSwgc2QgPSBtNCRwYXJbMl0sIHhpID0gbTQkcGFyWzNdKQojIHlmaXQgPC0geWZpdCpkaWZmKGgkbWlkc1sxOjJdKSpsZW5ndGgodDMpCiMgbGluZXMoeGZpdCwgeWZpdCwgY29sPSJibHVlIiwgbHdkPTIpCgpgYGAKCgoKYGBge3J9CiMgIyBGaXQgYSBndW1iZWwgZnVuY3Rpb24KIyBndW1fcGFyYW0gPSBndW0uZml0KHNtYWxsX2RmWywzXSkKIyBndW1fcGFyYW0kbWxlCiMgCiMgIyBUcnkgZml0dGluZyBhIEdFViBkaXN0cmlidXRpb24KIyBnZXZfcGFyYW0gPSBnZXYuZml0KHNtYWxsX2RmWywzXSkKIyBnZXZfcGFyYW0kbWxlCiMgCiMgIyBQbG90IGhpc3RvZ3JhbXMKIyAjIEd1bWJlbAojIGggPSBoaXN0KHNtYWxsX2RmWywzXSwgYnJlYWtzID0gMjUpCiMgIyBPdmVyc2V0IGEgZGVuc2l0eSBmdW5jdGlvbgojIHhmaXQ8LXNlcShtaW4oc21hbGxfZGZbLDNdKSxtYXgoc21hbGxfZGZbLDNdKSxsZW5ndGg9MjUwKQojIHlmaXQgPSBkZ3VtYmVsKHhmaXQsIGxvYyA9IGd1bV9wYXJhbSRtbGVbMV0sIHNjYWxlID0gZ3VtX3BhcmFtJG1sZVsyXSkKIyB5Zml0IDwtIHlmaXQqZGlmZihoJG1pZHNbMToyXSkqbGVuZ3RoKHNtYWxsX2RmWywzXSkKIyBsaW5lcyh4Zml0LCB5Zml0LCBjb2w9ImJsdWUiLCBsd2Q9MikKIyAKIyAjIEdFVgojIGggPSBoaXN0KHNtYWxsX2RmWywzXSwgYnJlYWtzID0gMjUpCiMgIyBPdmVyc2V0IGEgZGVuc2l0eSBmdW5jdGlvbgojIHhmaXQ8LXNlcShtaW4oc21hbGxfZGZbLDNdKSxtYXgoc21hbGxfZGZbLDNdKSxsZW5ndGg9MjUwKQojIHlmaXQgPSBkZ2V2KHhmaXQsIGxvYyA9IGdldl9wYXJhbSRtbGVbMV0sIHNjYWxlID0gZ2V2X3BhcmFtJG1sZVsyXSwgc2hhcGUgPSBnZXZfcGFyYW0kbWxlWzNdKQojIHlmaXQgPC0geWZpdCpkaWZmKGgkbWlkc1sxOjJdKSpsZW5ndGgoc21hbGxfZGZbLDNdKQojIGxpbmVzKHhmaXQsIHlmaXQsIGNvbD0iYmx1ZSIsIGx3ZD0yKQoKYGBgCgpUbyBmaXQgdGhlIGFib3ZlIGhpc3RvZ3JhbXMsdGhlIG9wdGltYWwgcGFyYW1ldGVycyB3ZXJlIGZpdCB1c2luZyBtYXhpbXVtIGxpa2VsaWhvb2QuIE5vdGUgdGhhdCB3aGlsZSB0aGVyZSB3ZXJlIGNvbnZlcmdlbmNlIGlzc3VlcyB1c2VkIGluIGZpdHRpbmcgdGhlIHNrZXctbm9ybWFsIGRpc3RyaWJ1dGlvbiwgdGhlcmUgd2VyZSBub3QgaXNzdWVzIHdpdGggZml0dGluZyB0aGUgR3VtYmVsIG9yIHRoZSBHRVYgZGlzdHJpYnV0aW9ucy4KCmBgYHtyfQojIEJlbG93IGFyZSB0aGUgb3B0aW1hbCBwYXJhbWV0ZXJzIGZvciB0aGUgc2Vjb25kIG1vZGVsCm5vcm1fcGFyYW1fZGYgPSBhcy5kYXRhLmZyYW1lKGNiaW5kKG1lYW4oc21hbGxfZGZbLDJdKSxzZChzbWFsbF9kZlssMl0pKSkKcm93bmFtZXMobm9ybV9wYXJhbV9kZikgPC0gYygiT3B0aW1hbCBQYXJhbWV0ZXJzIikKY29sbmFtZXMobm9ybV9wYXJhbV9kZikgPC0gYygiTWVhbiIsICJTdGFuZGFyZCBEZXZpYXRpb24iKQoKIyBEaXNwbGF5IGEgcHJldHR5IHRhYmxlCm5vcm1fcGFyYW1fZGYgJT4lIGthYmxlKGNhcHRpb24gPSAiT3B0aW1hbCBQYXJhbWV0ZXJzIGZvciB0aGUgTm9ybWFsIERpc3RyaWJ1dGlvbiIsIGRpZ2l0cyA9IDIpICU+JSBrYWJsZV9zdHlsaW5nKCJzdHJpcGVkIiwgZnVsbF93aWR0aCA9IEYpICU+JSBrYWJsZV9zdHlsaW5nKCkgJT4lIGZvb3Rub3RlKGdlbmVyYWwgPSAiVGhlIE1lYW4gV2FzIEVzdGltYXRlZCBVc2luZyB0aGUgU2FtcGxlIE1lYW4sIFNEIHdhcyBFc3RpbWF0ZWQgVXNpbmcgU2FtcGxlIFN0ZC4gRGV2LiIpCgojIFJld3JpdGUgbTIgYXMgdGhlIG9wdGltYWwgcGFyYW1ldGVycyBvZiBza2V3IG5vcm1hbApzbl9wYXJhbXMgPSBtMiRwYXIKCiMgRGlzcGxheSB0aGUgb3B0aW1hbCBza2V3LW5vcm1hbCBwYXJhbWV0ZXJzCnNuX3BhcmFtX2RmID0gYXMubWF0cml4KHQoc25fcGFyYW1zKSkKIyBzbl9wYXJhbV9kZgojIHJvd25hbWVzKHNuX3BhcmFtX2RmKSA8LSBjKCJPcHRpbWFsIFBhcmFtZXRlcnMiKQojIGNvbG5hbWVzKHNuX3BhcmFtX2RmKSA8LSBjKCJMb2NhdGlvbiIsICJTY2FsZSIsICJTaGFwZSIpCgojIERpc3BsYXkgYSBwcmV0dHkgdGFibGUKIyBzbl9wYXJhbV9kZiAlPiUga2FibGUoY2FwdGlvbiA9ICJPcHRpbWFsIFBhcmFtZXRlcnMgZm9yIHRoZSBTa2V3IE5vcm1hbCBEaXN0cmlidXRpb24iLCBkaWdpdHMgPSA0KSAlPiUga2FibGVfc3R5bGluZygic3RyaXBlZCIsIGZ1bGxfd2lkdGggPSBGKSAlPiUga2FibGVfc3R5bGluZygpICU+JSBmb290bm90ZShnZW5lcmFsID0gIkVzdGltYXRlZCBVc2luZyBNYXhpbXVtIExpa2VsaWhvb2QiKQoKIyBndW1fcGFyYW0kbWxlCgojIERpc3BsYXkgdGhlIG9wdGltYWwgR3VtYmVsIHBhcmFtZXRlcnMKZ3VtX3BhcmFtX2RmID0gYXMubWF0cml4KHQoYyhndW1fcGFyYW0kbWxlLDApKSkKIyBndW1fcGFyYW1fZGYKIyByb3duYW1lcyhndW1fcGFyYW1fZGYpIDwtIGMoIk9wdGltYWwgUGFyYW1ldGVycyIpCiMgY29sbmFtZXMoZ3VtX3BhcmFtX2RmKSA8LSBjKCJMb2NhdGlvbiIsICJTY2FsZSIpCgojIERpc3BsYXkgYSBwcmV0dHkgdGFibGUKIyBndW1fcGFyYW1fZGYgJT4lIGthYmxlKGNhcHRpb24gPSAiT3B0aW1hbCBQYXJhbWV0ZXJzIGZvciB0aGUgR3VtYmVsIERpc3RyaWJ1dGlvbiIsIGRpZ2l0cyA9IDQpICU+JSBrYWJsZV9zdHlsaW5nKCJzdHJpcGVkIiwgZnVsbF93aWR0aCA9IEYpICU+JSBrYWJsZV9zdHlsaW5nKCkgJT4lIGZvb3Rub3RlKGdlbmVyYWwgPSAiRXN0aW1hdGVkIFVzaW5nIE1heGltdW0gTGlrZWxpaG9vZCIpCgoKIyBUYWtlIG91dCB0aGUgb3B0aW1hbCBwYXJhbWV0ZXJzCmdldl9wYXJhbV9kZiA9IGFzLm1hdHJpeCh0KGdldl9wYXJhbSRtbGUpKQojIHJvd25hbWVzKGdldl9wYXJhbV9kZikgPC0gYygiT3B0aW1hbCBQYXJhbWV0ZXJzIikKIyBjb2xuYW1lcyhnZXZfcGFyYW1fZGYpIDwtIGMoIkxvY2F0aW9uIiwgIlNjYWxlIiwgIlNoYXBlIikKCiMgRGlzcGxheSBhIHByZXR0eSB0YWJsZQojIGdldl9wYXJhbV9kZiAlPiUga2FibGUoY2FwdGlvbiA9ICJPcHRpbWFsIFBhcmFtZXRlcnMgZm9yIHRoZSBHZW5lcmFsaXplZCBFeHRyZW1lIFZhbHVlIERpc3RyaWJ1dGlvbiIsIGRpZ2l0cyA9IDIpICU+JSBrYWJsZV9zdHlsaW5nKCJzdHJpcGVkIiwgZnVsbF93aWR0aCA9IEYpICU+JSBrYWJsZV9zdHlsaW5nKCkgJT4lIGZvb3Rub3RlKGdlbmVyYWwgPSAiRXN0aW1hdGVkIFVzaW5nIE1heGltdW0gTGlrZWxpaG9vZCIpCgojIENvbWJpbmUgYWxsIG9mIHRoZSBleHRyZW1lIHZhbHVlIGRpc3RyaWJ1dGlvbnMgdG9nZXRoZXIKZXZfcGFyYW1fZGYgPSBhcy5kYXRhLmZyYW1lKHJiaW5kKHNuX3BhcmFtX2RmLCBndW1fcGFyYW1fZGYsIGdldl9wYXJhbV9kZikpCnJvd25hbWVzKGV2X3BhcmFtX2RmKSA8LSBjKCJTa2V3IE5vcm1hbCIsICJHdW1iZWwiLCAiR0VWIikKY29sbmFtZXMoZXZfcGFyYW1fZGYpIDwtIGMoIkxvY2F0aW9uIiwgIlNjYWxlIiwgIlNoYXBlIikKCiMgQWRkIGEgbWlzc2luZyB2YWx1ZSBmb3IgR3VtYmVsIHNoYXBlCmV2X3BhcmFtX2RmWzIsM10gPC0gTkEKCiMgRGlzcGxheSBhIHByZXR0eSB0YWJsZQpldl9wYXJhbV9kZiAlPiUga2FibGUoY2FwdGlvbiA9ICJPcHRpbWFsIFBhcmFtZXRlcnMgZm9yIHRoZSBDYW5kaWRhdGUgRGlzdHJpYnV0aW9ucyIsIGRpZ2l0cyA9IDMpICU+JSBrYWJsZV9zdHlsaW5nKCJzdHJpcGVkIiwgZnVsbF93aWR0aCA9IEYpICU+JSBrYWJsZV9zdHlsaW5nKCkgJT4lIGZvb3Rub3RlKGdlbmVyYWwgPSAiRXN0aW1hdGVkIFVzaW5nIE1heGltdW0gTGlrZWxpaG9vZCIpCgoKYGBgCgpUbyBldmFsdWF0ZSB0aGUgbW9kZWwgZml0IG1vcmUgcmlnb3JvdXNseSwgSSBjb21wYXJlZCB0aGUgS3VsbGJhY2stTGVpYmxlciBkaXZlcmdlbmNlIGZvciBlYWNoIHRoZW9yZXRpY2FsIGRpc3RyaWJ1dGlvbi4KCmBgYHtyfQojIEZpcnN0LCBmaW5kIHRoZSBkZW5zaXR5IG9mIHRoZSBkYXRhCm0zX2RlbiA9IGhpc3Qoc21hbGxfZGZbLDNdLCBicmVha3MgPSAyNSwgZnJlcSA9IEZBTFNFLCBwbG90ID0gRkFMU0UpCiMgP2hpc3QKIyBtM19kZW4kZGVuc2l0eQoKIyBSZXdyaXRlIG0yIGFzIHRoZSBvcHRpbWFsIHBhcmFtZXRlcnMgb2Ygc2tldyBub3JtYWwKIyBzbl9wYXJhbXMgPSBtMiRwYXIKIyBzbl9wYXJhbXMKCiMgTmV4dCBjb21wdXRlIHRoZSBwcm9iYWJpbGl0eSBhdCBlYWNoIHBvaW50IGZvciB0aGUgZml0dGVkIG1vZGVscwojIyBTa2V3LW5vcm1hbApza25fZGVuID0gZHNub3JtKG0zX2RlbiRtaWRzLCBtZWFuID0gbTIkcGFyWzFdLCBzZCA9IG0yJHBhclsyXSwgeGkgPSBtMiRwYXJbM10pCiMjIEd1bWJlbApndW1iX2RlbiA9IGRndW1iZWwobTNfZGVuJG1pZHMsIGxvYyA9IGd1bV9wYXJhbSRtbGVbMV0sIHNjYWxlID0gZ3VtX3BhcmFtJG1sZVsyXSkKIyMgR0VWCmdldl9kZW4gPSBkZ2V2KG0zX2RlbiRtaWRzLCBsb2MgPSBnZXZfcGFyYW0kbWxlWzFdLCBzY2FsZSA9IGdldl9wYXJhbSRtbGVbMl0sIHNoYXBlID0gZ2V2X3BhcmFtJG1sZVszXSkKCiMgQ2FsY3VsYXRlIHRoZSBLLUwgZGl2ZXJnZW5jZXMgZm9yIGVhY2gKa2xfc2tuID0gS0xEKG0zX2RlbiRkZW5zaXR5LCBza25fZGVuKQprbF9ndW1iID0gS0xEKG0zX2RlbiRkZW5zaXR5LCBndW1iX2RlbikKa2xfZ2V2ID0gS0xEKG0zX2RlbiRkZW5zaXR5LCBnZXZfZGVuKQoKIyBDb21iaW5lIGludG8gYSBkYXRhIGZyYW1lCmtsX2RmID0gYXMuZGF0YS5mcmFtZShjYmluZChrbF9za24kbWVhbi5zdW0uS0xELCBrbF9ndW1iJG1lYW4uc3VtLktMRCwga2xfZ2V2JG1lYW4uc3VtLktMRCkpCgpyb3duYW1lcyhrbF9kZikgPC0gYygiTWVhbiBTdW0gSy1MIERpdmVyZ2VuY2UiKQpjb2xuYW1lcyhrbF9kZikgPC0gYygiU2tldy1Ob3JtYWwiLCAiR3VtYmVsIiwgIkdFViIpCgojIERpc3BsYXkgYSBwcmV0dHkgdGFibGUKa2xfZGYgJT4lIGthYmxlKGNhcHRpb24gPSAiQ29tcGFyaW5nIEstTCBEaXZlcmdlbmNlcyBCeSBNb2RlbCBGaXRzIiwgZGlnaXRzID0gMikgJT4lIGthYmxlX3N0eWxpbmcoInN0cmlwZWQiLCBmdWxsX3dpZHRoID0gRikgJT4lIGthYmxlX3N0eWxpbmcoKSAKYGBgCgpgYGB7cn0KIyBMZXQncyBzZWUgdGhlIHZhbHVlcyBvZiB0aGUgbG9zc2VzCnRvdGFsX2xvc3NfZGYgPSBhcy5kYXRhLmZyYW1lKHQoY29sU3Vtcyh0ZXN0X2xvc3MpKSkKcm93bmFtZXModG90YWxfbG9zc19kZikgPC0gYygiTG9zc2VzIGJ5IE1vZGVsIikKY29sbmFtZXModG90YWxfbG9zc19kZikgPC0gY29sbmFtZXModjFfMjAwOF9hbGxldGZbWzFdXSlbLTFdCgojIFN1YnNldCB0aGUgZGF0YSBmcmFtZXMKZmlyc3RfNCA8LSB0b3RhbF9sb3NzX2RmWzEsMTo0XQpsYXN0XzQgPC0gdG90YWxfbG9zc19kZlsxLDU6OF0KCiMgUHJpbnQgdGhlc2Ugb3V0CmZpcnN0XzQgJT4lIGthYmxlKGNhcHRpb24gPSAiTG9zc2VzIE92ZXIgdGhlIExhc3QgMjUwIFRyYWRpbmcgRGF5cyBpbiAyMDA4IGZvciB0aGUgTXVsdGl2YXJpYXRlIENBVmlhUiBNb2RlbHMiLCBkaWdpdHMgPSAzKSAlPiUga2FibGVfc3R5bGluZygic3RyaXBlZCIsIGZ1bGxfd2lkdGggPSBGKSAlPiUga2FibGVfc3R5bGluZygpIApsYXN0XzQgJT4lIGthYmxlKGNhcHRpb24gPSAiTG9zc2VzIE92ZXIgdGhlIExhc3QgMjUwIFRyYWRpbmcgRGF5cyBpbiAyMDA4IGZvciB0aGUgVW5pdmFyaWF0ZSBDQVZpYVIgTW9kZWxzIiwgZGlnaXRzID0gMykgJT4lIGthYmxlX3N0eWxpbmcoInN0cmlwZWQiLCBmdWxsX3dpZHRoID0gRikgJT4lIGthYmxlX3N0eWxpbmcoKSAKYGBgCgpCYXNlZCBvbiB0aGUgbG9zc2VzIGZvciBlYWNoIG1vZGVsIGR1cmluZyB0aGUgbGFzdCAyNTAgdHJhZGluZyBkYXlzIGluIDIwMDgsIGl0IGxvb2tzIGxpa2UgdGhlIGJlc3Qgb3B0aW9ucyBhcmUgdGhlIG11bHRpdmFyaWF0ZSBDQVZpYVIgbW9kZWwgd2l0aG91dCBBUiB0ZXJtcyBmb3IgdGhlIG11bHRpdmFyaWF0ZSBtb2RlbCBjbGFzcyBhbmQgdGhlIHN5bW1ldHJpYyBhYnNvbHV0ZSB2YWx1ZSBtb2RlbCBmb3IgdGhlIHVuaXZhcmlhdGUgbW9kZWwgY2xhc3MuIFRoZSBmdWxsIG1vZGVsIHNwZWNpZmljYXRpb25zIGNhbiBiZSBmb3VuZCBpbiB0aGUgYXBwZW5kaXguCgpDb2luY2lkZW50YWxseSwgdGhlc2UgYXJlIGFtb25nIHRoZSBzaW1wbGVzdCBtb2RlbHMgYXZhaWxhYmxlIGFtb25nIHRoZSBtb2RlbHMgcGxvdHRlZCBhYm92ZS4gQSBuYXR1cmFsIGNyaXRpY2lzbSBvZiB0aGlzIGFwcHJvYWNoIGlzIHRoYXQgdGhlIGxvc3NlcyBhcmUgbG93ZXIgZm9yIHRoZSBDQVZpYVIgc3BlY2lmaWNhdGlvbnMgd2l0aG91dCBsYWdnZWQgcHJlZGljdG9ycy4gVGhpcyBpcyBhIGZhaXIgcG9pbnQsIGhvd2V2ZXIsIHRoZSBwZXJpb2Qgb2YgMjAwOCBpcyBhIHBlcmlvZCBvZiBleHRyZW1lIGNyaXNpcywgYW5kIGEgc2ltcGxlciwgQVJNQS1zdHlsZSBtb2RlbCBtaWdodCBzZWVtIHRvIHdvcmsgYmV0dGVyIG90aGVyIHRoaW5ncyBlcXVhbC4gRnV0dXJlIHdvcmsgY2FuIGV4dGVuZCB0aGlzIHdvcmsgdG8gb3RoZXIgcGVyaW9kcy4gU2luY2UgdGhlc2UgYXJlIHRoZSBiZXN0IHR3byBvcHRpb25zIGR1cmluZyB0aGlzIHBlcmlvZCBvZiBpbnRlcmVzdCwgdGhlIG5leHQgc3RlcCBpcyB0byBmaW5kIHJlYXNvbmFibGUgcGFyYW1ldHJpYyBkaXN0cmlidXRpb25zIHRvIG1vZGVsIHRoZWlyIHZhbHVlcy4KCiMjIEZpbmRpbmcgRGlzdHJpYnV0aW9ucyBvZiB0aGUgRm9yZWNhc3RzCgpUbyBmaXQgdGhlIEhpZGRlbiBNYXJrb3YgTW9kZWwsIGl0IGlzIG5lY2Vzc2FyeSB0byBmaW5kIGRpc3RyaWJ1dGlvbnMgdGhhdCBhcHByb3ByaWF0ZWx5IGZpdCB0aGUgdHdvIG1vZGVscyBhYm92ZS4gV2hpbGUgdGhlIGRpc3RyaWJ1dGlvbiBvZiBwcmVkaWN0aW9ucyBmcm9tIHRoZSBtdWx0aXZhcmlhdGUgbW9kZWwgaXMgZmFpcmx5IHdlbGwtYXBwcm94aW1hdGVkIGJ5IGEgbm9ybWFsIGRpc3RyaWJ1dGlvbiwgdGhlIGRpc3RyaWJ1dGlvbiBvZiBwcmVkaWN0aW9ucyBmcm9tIHRoZSB1bml2YXJpYXRlIG1vZGVsIHdhcyBoaWdobHkgbGVmdC1za2V3ZWQsIHdoaWNoIG1ha2VzIGZpdHRpbmcgYSBkaXN0cmlidXRpb24gZGlmZmljdWx0LgoKVGhlIGZpcnN0IHN0ZXAgd2FzIHRvIHRyeSB0cmFuc2Zvcm1hdGlvbnMgb2YgdGhlIGFmb3JlbWVudGlvbmVkIHByZWRpY3Rpb25zIGZyb20gdGhlIHVuaXZhcmlhdGUgbW9kZWwsIG5hbWVseSAkXHNxcnR7XG1heCh4KzEpIC14fSQsICRcbG9nX3sxMH0gKFxtYXgoeCsxKSAteCkkLCBhbmQgJDEvKFxtYXgoeCsxKSAteCkkIGZvbGxvd2luZyB0aGUgc3VnZ2VzdGlvbnMgZm91bmQgaGVyZSBbQEthc3NhbWJhcmFdLiBXaGlsZSB0aGVzZSBkaWQgKGluIHNvbWUgY2FzZXMpIGVsaW1pbmF0ZSB0aGUgbGVmdC1za2V3LCBpdCBvZnRlbiBjcmVhdGVkIGEgbW9yZSBwcm9ub3VuY2VkIHJpZ2h0LXNrZXchIFRodXMsIEkgYXR0ZW1wdGVkIHRvIG1vZGVsIHRoZSBkYXRhIHdpdGhvdXQgdHJhbnNmb3JtYXRpb24uCgpUaGVyZSBhcmUgbWFueSBjYW5kaWRhdGUgZGlzdHJpYnV0aW9ucyB0aGF0IGNvdWxkIGJlIHVzZWQgdG8gbW9kZWwgdGhlIGVtcGlyaWNhbCBkaXN0cmlidXRpb24gb2YgdmFsdWVzIGZyb20gdGhlIHVuaXZhcmlhdGUgQ0FWaWFSIG1vZGVsLCBidXQgdGhlIHRocmVlIHRoYXQgc3Rvb2Qgb3V0IGFyZToKCjEuIFRoZSBTa2V3IE5vcm1hbCBEaXN0cmlidXRpb24gKHBhcmFtZXRlcml6ZWQgYnkgbG9jYXRpb24sIHNjYWxlLCBhbmQgc2hhcGUgcGFyYW1ldGVycykKMi4gVGhlIEd1bWJlbCBEaXN0cmlidXRpb24gKHBhcmFtZXRlcml6ZWQgYnkgbG9jYXRpb24gYW5kIHNjYWxlIHBhcmFtZXRlcnMpCjMuIFRoZSBHZW5lcmFsaXplZCBFeHRyZW1lIFZhbHVlIERpc3RyaWJ1dGlvbiAocGFyYW1ldGVyaXplZCBieSBsb2NhdGlvbiwgc2NhbGUsIGFuZCBzaGFwZSBwYXJhbWV0ZXJzKQoKCgpgYGB7cn0KIyBFeHRyYWN0IHRoZSBkYXRhCnNtYWxsX2RmID0gdjFfMjAwOF9hbGxldGZbWzFdXVssYygxLDIsNildCgojIEFkZCAxCiMgc21hbGxfZGYyID0gc21hbGxfZGYgKyAxCgojIFRoZXNlIGZpdHMgZG9uJ3Qgd29yayB2ZXJ5IHdlbGwKIyBoaXN0KGxvZyhzbWFsbF9kZjJbLDJdKSwgYnJlYWtzID0gMjUpCiMgaGlzdChzbWFsbF9kZjJbLDNdLCBicmVha3MgPSAyNSkKIyBoaXN0KGxvZyhzbWFsbF9kZjJbLDNdKSwgYnJlYWtzID0gMjUpCiMgaGlzdCgoc21hbGxfZGZbLDNdKSwgYnJlYWtzID0gMjUpCgojIHNtYWxsX2RmMgojID9zbm9ybUZpdAoKIyBMZXQncyB0cnkgYW5vdGhlciB0cmFuc2Zvcm1hdGlvbgojIHQxID0gc3FydChtYXgoc21hbGxfZGZbLDNdKzEpIC0gc21hbGxfZGZbLDNdKQojIHQyID0gbG9nMTAobWF4KHNtYWxsX2RmWywzXSsxKSAtIHNtYWxsX2RmWywzXSkKIyB0MyA9IDEvKG1heChzbWFsbF9kZlssM10rMSkgLSBzbWFsbF9kZlssM10pCgojIFBsb3QgdGhlIHRyYW5zZm9ybWF0aW9ucwojIGhpc3QodDEsIGJyZWFrcyA9IDI1KQojIGhpc3QodDIsIGJyZWFrcyA9IDI1KQojIGhpc3QodDMsIGJyZWFrcyA9IDI1KQoKCmBgYAoKCmBgYHtyfQojIEZpdCBhIHNrZXcgbm9ybWFsCm0xID0gc25vcm1GaXQoc21hbGxfZGZbLDJdKQptMiA9IHNub3JtRml0KHNtYWxsX2RmWywzXSkKCiMgbTEKCiMgc25vcm1GaXQoc21hbGxfZGZbLDJdKzEpCiMgc25vcm1GaXQoc21hbGxfZGZbLDNdKzEpCiMgVGhlc2UgbWF5IG5vdCB3b3JrIHZlcnkgd2VsbAoKIyBzcXVhcmVfdmFsID0gc21hbGxfZGZbLDNdXjIKIyBtMyA9IHNub3JtRml0KHNxdWFyZV92YWwpCiMgbTQgPSBzbm9ybUZpdCh0MykKIyBtNAoKCgojIGhpc3QoKHNtYWxsX2RmWywzXSleMiwgYnJlYWtzID0gMjUpCmBgYAoKCmBgYHtyfQojIEZpdCBhIGd1bWJlbCBmdW5jdGlvbgpndW1fcGFyYW0gPSBndW0uZml0KHNtYWxsX2RmWywzXSwgc2hvdyA9IEZBTFNFKQojID9ndW0uZml0CiMgZ3VtX3BhcmFtJG1sZQoKIyBUcnkgZml0dGluZyBhIEdFViBkaXN0cmlidXRpb24KZ2V2X3BhcmFtID0gZ2V2LmZpdChzbWFsbF9kZlssM10sIHNob3cgPSBGQUxTRSkKIyBnZXZfcGFyYW0kbWxlCgojICMgUGxvdCBoaXN0b2dyYW1zCiMgIyBHdW1iZWwKIyBoID0gaGlzdChzbWFsbF9kZlssM10sIGJyZWFrcyA9IDI1KQojICMgT3ZlcnNldCBhIGRlbnNpdHkgZnVuY3Rpb24KIyB4Zml0PC1zZXEobWluKHNtYWxsX2RmWywzXSksbWF4KHNtYWxsX2RmWywzXSksbGVuZ3RoPTI1MCkKIyB5Zml0ID0gZGd1bWJlbCh4Zml0LCBsb2MgPSBndW1fcGFyYW0kbWxlWzFdLCBzY2FsZSA9IGd1bV9wYXJhbSRtbGVbMl0pCiMgeWZpdCA8LSB5Zml0KmRpZmYoaCRtaWRzWzE6Ml0pKmxlbmd0aChzbWFsbF9kZlssM10pCiMgbGluZXMoeGZpdCwgeWZpdCwgY29sPSJibHVlIiwgbHdkPTIpCiMgCiMgIyBHRVYKIyBoID0gaGlzdChzbWFsbF9kZlssM10sIGJyZWFrcyA9IDI1KQojICMgT3ZlcnNldCBhIGRlbnNpdHkgZnVuY3Rpb24KIyB4Zml0PC1zZXEobWluKHNtYWxsX2RmWywzXSksbWF4KHNtYWxsX2RmWywzXSksbGVuZ3RoPTI1MCkKIyB5Zml0ID0gZGdldih4Zml0LCBsb2MgPSBnZXZfcGFyYW0kbWxlWzFdLCBzY2FsZSA9IGdldl9wYXJhbSRtbGVbMl0sIHNoYXBlID0gZ2V2X3BhcmFtJG1sZVszXSkKIyB5Zml0IDwtIHlmaXQqZGlmZihoJG1pZHNbMToyXSkqbGVuZ3RoKHNtYWxsX2RmWywzXSkKIyBsaW5lcyh4Zml0LCB5Zml0LCBjb2w9ImJsdWUiLCBsd2Q9MikKCnBhcihtZnJvdyA9IGMoMSwyKSkKCiMgTGV0J3MgbG9vayBhdCB0aGUgZGF0YQpoID0gaGlzdChzbWFsbF9kZlssMl0sIGJyZWFrcyA9IDI1LCB4bGFiID0gIk1vZGVsZWQgVmFsdWVzIiwgbWFpbiA9ICJNdWx0aXZhcmlhdGUgQ0FWaWFSIikKIyBPdmVyc2V0IGEgZGVuc2l0eSBmdW5jdGlvbgp4Zml0PC1zZXEobWluKHNtYWxsX2RmWywyXSksbWF4KHNtYWxsX2RmWywyXSksbGVuZ3RoPTI1MCkKeWZpdCA9IGRzbm9ybSh4Zml0LCBtZWFuID0gbTEkcGFyWzFdLCBzZCA9IG0xJHBhclsyXSwgeGkgPSBtMSRwYXJbM10pCnlmaXQgPC0geWZpdCpkaWZmKGgkbWlkc1sxOjJdKSpsZW5ndGgoc21hbGxfZGZbLDJdKQpsaW5lcyh4Zml0LCB5Zml0LCBjb2w9ImJsdWUiLCBsd2Q9MikKIyBPdmVyc2V0IGEgbm9ybWFsIGRlbnNpdHkgZnVuY3Rpb24KeGZpdDwtc2VxKG1pbihzbWFsbF9kZlssMl0pLG1heChzbWFsbF9kZlssMl0pLGxlbmd0aD0yNTApCnlmaXRfbiA9IGRub3JtKHhmaXQsIG1lYW4gPSBtZWFuKHNtYWxsX2RmWywyXSksIHNkID0gc2Qoc21hbGxfZGZbLDJdKSkKeWZpdF9uIDwtIHlmaXRfbipkaWZmKGgkbWlkc1sxOjJdKSpsZW5ndGgoc21hbGxfZGZbLDJdKQpsaW5lcyh4Zml0LCB5Zml0X24sIGNvbD0icmVkIiwgbHdkPTIsIGx0eSA9IDIpCgojIEFkZCBhIGxlZ2VuZApsZWdlbmQoInRvcGxlZnQiLCBsZWdlbmQgPSBjKCJOb3JtYWwiLCAiU2tldyBOb3JtYWwiKSwgY29sID0gYygiYmx1ZSIsICJyZWQiKSwgbHR5ID0gYygxLDIpLCBsd2QgPSBjKDIsMikpCgoKCiMgTGV0J3MgbG9vayBhdCB0aGUgc2Vjb25kIHNldCBvZiBkYXRhCmggPSBoaXN0KHNtYWxsX2RmWywzXSwgYnJlYWtzID0gMjUsIHhsYWIgPSAiTW9kZWxlZCBWYWx1ZXMiLCBtYWluID0gIlVuaXZhcmlhdGUgQ0FWaWFSIikKIyBPdmVyc2V0IGEgZGVuc2l0eSBmdW5jdGlvbiAtIFNrZXcgTm9ybWFsCnhmaXQ8LXNlcShtaW4oc21hbGxfZGZbLDNdKSxtYXgoc21hbGxfZGZbLDNdKSxsZW5ndGg9MjUwKQp5Zml0ID0gZHNub3JtKHhmaXQsIG1lYW4gPSBtMiRwYXJbMV0sIHNkID0gbTIkcGFyWzJdLCB4aSA9IG0yJHBhclszXSkKeWZpdCA8LSB5Zml0KmRpZmYoaCRtaWRzWzE6Ml0pKmxlbmd0aChzbWFsbF9kZlssM10pCmxpbmVzKHhmaXQsIHlmaXQsIGNvbD0iYmx1ZSIsIGx3ZD0yKQojIE92ZXJzZXQgYSBkZW5zaXR5IGZ1bmN0aW9uIC0gR3VtYmVsCnhmaXQ8LXNlcShtaW4oc21hbGxfZGZbLDNdKSxtYXgoc21hbGxfZGZbLDNdKSxsZW5ndGg9MjUwKQp5Zml0ID0gZGd1bWJlbCh4Zml0LCBsb2MgPSBndW1fcGFyYW0kbWxlWzFdLCBzY2FsZSA9IGd1bV9wYXJhbSRtbGVbMl0pCnlmaXQgPC0geWZpdCpkaWZmKGgkbWlkc1sxOjJdKSpsZW5ndGgoc21hbGxfZGZbLDNdKQpsaW5lcyh4Zml0LCB5Zml0LCBjb2w9InJlZCIsIGx3ZD0yKQojIE92ZXJzZXQgYSBkZW5zaXR5IGZ1bmN0aW9uIC0gR0VWCnhmaXQ8LXNlcShtaW4oc21hbGxfZGZbLDNdKSxtYXgoc21hbGxfZGZbLDNdKSxsZW5ndGg9MjUwKQp5Zml0ID0gZGdldih4Zml0LCBsb2MgPSBnZXZfcGFyYW0kbWxlWzFdLCBzY2FsZSA9IGdldl9wYXJhbSRtbGVbMl0sIHNoYXBlID0gZ2V2X3BhcmFtJG1sZVszXSkKeWZpdCA8LSB5Zml0KmRpZmYoaCRtaWRzWzE6Ml0pKmxlbmd0aChzbWFsbF9kZlssM10pCmxpbmVzKHhmaXQsIHlmaXQsIGNvbD0iZ3JlZW4iLCBsd2Q9MikKCiMgQWRkIGEgbGVnZW5kCmxlZ2VuZCgidG9wbGVmdCIsIGxlZ2VuZCA9IGMoIlNrZXcgTm9ybWFsIiwgIkd1bWJlbCIsICJHRVYiKSwgY29sID0gYygiYmx1ZSIsICJyZWQiLCAiZ3JlZW4iKSwgbHR5ID0gYygxLDEsMSksIGx3ZCA9IGMoMiwyLDIpKQoKIyBwYXIobWZyb3cgPSBjKDEsMykpCiMgCiMgIyBMZXQncyBsb29rIGF0IHRoZSBkYXRhCiMgaCA9IGhpc3Qoc21hbGxfZGZbLDJdLCBicmVha3MgPSAyNSkKIyAjIE92ZXJzZXQgYSBkZW5zaXR5IGZ1bmN0aW9uCiMgeGZpdDwtc2VxKG1pbihzbWFsbF9kZlssMl0pLG1heChzbWFsbF9kZlssMl0pLGxlbmd0aD0yNTApCiMgeWZpdCA9IGRzbm9ybSh4Zml0LCBtZWFuID0gbTEkcGFyWzFdLCBzZCA9IG0xJHBhclsyXSwgeGkgPSBtMSRwYXJbM10pCiMgeWZpdCA8LSB5Zml0KmRpZmYoaCRtaWRzWzE6Ml0pKmxlbmd0aChzbWFsbF9kZlssMl0pCiMgbGluZXMoeGZpdCwgeWZpdCwgY29sPSJibHVlIiwgbHdkPTIpCiMgIyBPdmVyc2V0IGEgbm9ybWFsIGRlbnNpdHkgZnVuY3Rpb24KIyB4Zml0PC1zZXEobWluKHNtYWxsX2RmWywyXSksbWF4KHNtYWxsX2RmWywyXSksbGVuZ3RoPTI1MCkKIyB5Zml0X24gPSBkbm9ybSh4Zml0LCBtZWFuID0gbWVhbihzbWFsbF9kZlssMl0pLCBzZCA9IHNkKHNtYWxsX2RmWywyXSkpCiMgeWZpdF9uIDwtIHlmaXRfbipkaWZmKGgkbWlkc1sxOjJdKSpsZW5ndGgoc21hbGxfZGZbLDJdKQojIGxpbmVzKHhmaXQsIHlmaXRfbiwgY29sPSJyZWQiLCBsd2Q9MiwgbHR5ID0gMikKIyAKIyAjIExldCdzIGxvb2sgYXQgdGhlIHNlY29uZCBzZXQgb2YgZGF0YQojIGggPSBoaXN0KHNtYWxsX2RmWywzXSwgYnJlYWtzID0gMjUpCiMgIyBPdmVyc2V0IGEgZGVuc2l0eSBmdW5jdGlvbgojIHhmaXQ8LXNlcShtaW4oc21hbGxfZGZbLDNdKSxtYXgoc21hbGxfZGZbLDNdKSxsZW5ndGg9MjUwKQojIHlmaXQgPSBkc25vcm0oeGZpdCwgbWVhbiA9IG0yJHBhclsxXSwgc2QgPSBtMiRwYXJbMl0sIHhpID0gbTIkcGFyWzNdKQojIHlmaXQgPC0geWZpdCpkaWZmKGgkbWlkc1sxOjJdKSpsZW5ndGgoc21hbGxfZGZbLDNdKQojIGxpbmVzKHhmaXQsIHlmaXQsIGNvbD0iYmx1ZSIsIGx3ZD0yKQojIAojICMgIyBMZXQncyBsb29rIGF0IHRoZSBzZWNvbmQgc2V0IG9mIGRhdGEKIyAjIGggPSBoaXN0KHNxdWFyZV92YWwsIGJyZWFrcyA9IDI1KQojICMgIyBPdmVyc2V0IGEgZGVuc2l0eSBmdW5jdGlvbgojICMgeGZpdDwtc2VxKG1pbihzcXVhcmVfdmFsKSxtYXgoc3F1YXJlX3ZhbCksbGVuZ3RoPTI1MCkKIyAjIHlmaXQgPSBkc25vcm0oeGZpdCwgbWVhbiA9IG0zJHBhclsxXSwgc2QgPSBtMyRwYXJbMl0sIHhpID0gbTMkcGFyWzNdKQojICMgeWZpdCA8LSB5Zml0KmRpZmYoaCRtaWRzWzE6Ml0pKmxlbmd0aChzcXVhcmVfdmFsKQojICMgbGluZXMoeGZpdCwgeWZpdCwgY29sPSJibHVlIiwgbHdkPTIpCiMgCiMgIyBMZXQncyBsb29rIGF0IHRoZSBzZWNvbmQgc2V0IG9mIGRhdGEKIyBoID0gaGlzdCh0MywgYnJlYWtzID0gMjUpCiMgIyBPdmVyc2V0IGEgZGVuc2l0eSBmdW5jdGlvbgojIHhmaXQ8LXNlcShtaW4odDMpLG1heCh0MyksbGVuZ3RoPTI1MCkKIyB5Zml0ID0gZHNub3JtKHhmaXQsIG1lYW4gPSBtNCRwYXJbMV0sIHNkID0gbTQkcGFyWzJdLCB4aSA9IG00JHBhclszXSkKIyB5Zml0IDwtIHlmaXQqZGlmZihoJG1pZHNbMToyXSkqbGVuZ3RoKHQzKQojIGxpbmVzKHhmaXQsIHlmaXQsIGNvbD0iYmx1ZSIsIGx3ZD0yKQoKYGBgCgoKCmBgYHtyfQojICMgRml0IGEgZ3VtYmVsIGZ1bmN0aW9uCiMgZ3VtX3BhcmFtID0gZ3VtLmZpdChzbWFsbF9kZlssM10pCiMgZ3VtX3BhcmFtJG1sZQojIAojICMgVHJ5IGZpdHRpbmcgYSBHRVYgZGlzdHJpYnV0aW9uCiMgZ2V2X3BhcmFtID0gZ2V2LmZpdChzbWFsbF9kZlssM10pCiMgZ2V2X3BhcmFtJG1sZQojIAojICMgUGxvdCBoaXN0b2dyYW1zCiMgIyBHdW1iZWwKIyBoID0gaGlzdChzbWFsbF9kZlssM10sIGJyZWFrcyA9IDI1KQojICMgT3ZlcnNldCBhIGRlbnNpdHkgZnVuY3Rpb24KIyB4Zml0PC1zZXEobWluKHNtYWxsX2RmWywzXSksbWF4KHNtYWxsX2RmWywzXSksbGVuZ3RoPTI1MCkKIyB5Zml0ID0gZGd1bWJlbCh4Zml0LCBsb2MgPSBndW1fcGFyYW0kbWxlWzFdLCBzY2FsZSA9IGd1bV9wYXJhbSRtbGVbMl0pCiMgeWZpdCA8LSB5Zml0KmRpZmYoaCRtaWRzWzE6Ml0pKmxlbmd0aChzbWFsbF9kZlssM10pCiMgbGluZXMoeGZpdCwgeWZpdCwgY29sPSJibHVlIiwgbHdkPTIpCiMgCiMgIyBHRVYKIyBoID0gaGlzdChzbWFsbF9kZlssM10sIGJyZWFrcyA9IDI1KQojICMgT3ZlcnNldCBhIGRlbnNpdHkgZnVuY3Rpb24KIyB4Zml0PC1zZXEobWluKHNtYWxsX2RmWywzXSksbWF4KHNtYWxsX2RmWywzXSksbGVuZ3RoPTI1MCkKIyB5Zml0ID0gZGdldih4Zml0LCBsb2MgPSBnZXZfcGFyYW0kbWxlWzFdLCBzY2FsZSA9IGdldl9wYXJhbSRtbGVbMl0sIHNoYXBlID0gZ2V2X3BhcmFtJG1sZVszXSkKIyB5Zml0IDwtIHlmaXQqZGlmZihoJG1pZHNbMToyXSkqbGVuZ3RoKHNtYWxsX2RmWywzXSkKIyBsaW5lcyh4Zml0LCB5Zml0LCBjb2w9ImJsdWUiLCBsd2Q9MikKCmBgYAoKVG8gZml0IHRoZSBhYm92ZSBoaXN0b2dyYW1zLHRoZSBvcHRpbWFsIHBhcmFtZXRlcnMgd2VyZSBmaXQgdXNpbmcgbWF4aW11bSBsaWtlbGlob29kLiBOb3RlIHRoYXQgd2hpbGUgdGhlcmUgd2VyZSBjb252ZXJnZW5jZSBpc3N1ZXMgdXNlZCBpbiBmaXR0aW5nIHRoZSBza2V3LW5vcm1hbCBkaXN0cmlidXRpb24sIHRoZXJlIHdlcmUgbm90IGlzc3VlcyB3aXRoIGZpdHRpbmcgdGhlIEd1bWJlbCBvciB0aGUgR0VWIGRpc3RyaWJ1dGlvbnMuCgpgYGB7cn0KIyBCZWxvdyBhcmUgdGhlIG9wdGltYWwgcGFyYW1ldGVycyBmb3IgdGhlIHNlY29uZCBtb2RlbApub3JtX3BhcmFtX2RmID0gYXMuZGF0YS5mcmFtZShjYmluZChtZWFuKHNtYWxsX2RmWywyXSksc2Qoc21hbGxfZGZbLDJdKSkpCnJvd25hbWVzKG5vcm1fcGFyYW1fZGYpIDwtIGMoIk9wdGltYWwgUGFyYW1ldGVycyIpCmNvbG5hbWVzKG5vcm1fcGFyYW1fZGYpIDwtIGMoIk1lYW4iLCAiU3RhbmRhcmQgRGV2aWF0aW9uIikKCiMgRGlzcGxheSBhIHByZXR0eSB0YWJsZQpub3JtX3BhcmFtX2RmICU+JSBrYWJsZShjYXB0aW9uID0gIk9wdGltYWwgUGFyYW1ldGVycyBmb3IgdGhlIE5vcm1hbCBEaXN0cmlidXRpb24iLCBkaWdpdHMgPSAyKSAlPiUga2FibGVfc3R5bGluZygic3RyaXBlZCIsIGZ1bGxfd2lkdGggPSBGKSAlPiUga2FibGVfc3R5bGluZygpICU+JSBmb290bm90ZShnZW5lcmFsID0gIlRoZSBNZWFuIFdhcyBFc3RpbWF0ZWQgVXNpbmcgdGhlIFNhbXBsZSBNZWFuLCBTRCB3YXMgRXN0aW1hdGVkIFVzaW5nIFNhbXBsZSBTdGQuIERldi4iKQoKIyBSZXdyaXRlIG0yIGFzIHRoZSBvcHRpbWFsIHBhcmFtZXRlcnMgb2Ygc2tldyBub3JtYWwKc25fcGFyYW1zID0gbTIkcGFyCgojIERpc3BsYXkgdGhlIG9wdGltYWwgc2tldy1ub3JtYWwgcGFyYW1ldGVycwpzbl9wYXJhbV9kZiA9IGFzLm1hdHJpeCh0KHNuX3BhcmFtcykpCiMgc25fcGFyYW1fZGYKIyByb3duYW1lcyhzbl9wYXJhbV9kZikgPC0gYygiT3B0aW1hbCBQYXJhbWV0ZXJzIikKIyBjb2xuYW1lcyhzbl9wYXJhbV9kZikgPC0gYygiTG9jYXRpb24iLCAiU2NhbGUiLCAiU2hhcGUiKQoKIyBEaXNwbGF5IGEgcHJldHR5IHRhYmxlCiMgc25fcGFyYW1fZGYgJT4lIGthYmxlKGNhcHRpb24gPSAiT3B0aW1hbCBQYXJhbWV0ZXJzIGZvciB0aGUgU2tldyBOb3JtYWwgRGlzdHJpYnV0aW9uIiwgZGlnaXRzID0gNCkgJT4lIGthYmxlX3N0eWxpbmcoInN0cmlwZWQiLCBmdWxsX3dpZHRoID0gRikgJT4lIGthYmxlX3N0eWxpbmcoKSAlPiUgZm9vdG5vdGUoZ2VuZXJhbCA9ICJFc3RpbWF0ZWQgVXNpbmcgTWF4aW11bSBMaWtlbGlob29kIikKCiMgZ3VtX3BhcmFtJG1sZQoKIyBEaXNwbGF5IHRoZSBvcHRpbWFsIEd1bWJlbCBwYXJhbWV0ZXJzCmd1bV9wYXJhbV9kZiA9IGFzLm1hdHJpeCh0KGMoZ3VtX3BhcmFtJG1sZSwwKSkpCiMgZ3VtX3BhcmFtX2RmCiMgcm93bmFtZXMoZ3VtX3BhcmFtX2RmKSA8LSBjKCJPcHRpbWFsIFBhcmFtZXRlcnMiKQojIGNvbG5hbWVzKGd1bV9wYXJhbV9kZikgPC0gYygiTG9jYXRpb24iLCAiU2NhbGUiKQoKIyBEaXNwbGF5IGEgcHJldHR5IHRhYmxlCiMgZ3VtX3BhcmFtX2RmICU+JSBrYWJsZShjYXB0aW9uID0gIk9wdGltYWwgUGFyYW1ldGVycyBmb3IgdGhlIEd1bWJlbCBEaXN0cmlidXRpb24iLCBkaWdpdHMgPSA0KSAlPiUga2FibGVfc3R5bGluZygic3RyaXBlZCIsIGZ1bGxfd2lkdGggPSBGKSAlPiUga2FibGVfc3R5bGluZygpICU+JSBmb290bm90ZShnZW5lcmFsID0gIkVzdGltYXRlZCBVc2luZyBNYXhpbXVtIExpa2VsaWhvb2QiKQoKCiMgVGFrZSBvdXQgdGhlIG9wdGltYWwgcGFyYW1ldGVycwpnZXZfcGFyYW1fZGYgPSBhcy5tYXRyaXgodChnZXZfcGFyYW0kbWxlKSkKIyByb3duYW1lcyhnZXZfcGFyYW1fZGYpIDwtIGMoIk9wdGltYWwgUGFyYW1ldGVycyIpCiMgY29sbmFtZXMoZ2V2X3BhcmFtX2RmKSA8LSBjKCJMb2NhdGlvbiIsICJTY2FsZSIsICJTaGFwZSIpCgojIERpc3BsYXkgYSBwcmV0dHkgdGFibGUKIyBnZXZfcGFyYW1fZGYgJT4lIGthYmxlKGNhcHRpb24gPSAiT3B0aW1hbCBQYXJhbWV0ZXJzIGZvciB0aGUgR2VuZXJhbGl6ZWQgRXh0cmVtZSBWYWx1ZSBEaXN0cmlidXRpb24iLCBkaWdpdHMgPSAyKSAlPiUga2FibGVfc3R5bGluZygic3RyaXBlZCIsIGZ1bGxfd2lkdGggPSBGKSAlPiUga2FibGVfc3R5bGluZygpICU+JSBmb290bm90ZShnZW5lcmFsID0gIkVzdGltYXRlZCBVc2luZyBNYXhpbXVtIExpa2VsaWhvb2QiKQoKIyBDb21iaW5lIGFsbCBvZiB0aGUgZXh0cmVtZSB2YWx1ZSBkaXN0cmlidXRpb25zIHRvZ2V0aGVyCmV2X3BhcmFtX2RmID0gYXMuZGF0YS5mcmFtZShyYmluZChzbl9wYXJhbV9kZiwgZ3VtX3BhcmFtX2RmLCBnZXZfcGFyYW1fZGYpKQpyb3duYW1lcyhldl9wYXJhbV9kZikgPC0gYygiU2tldyBOb3JtYWwiLCAiR3VtYmVsIiwgIkdFViIpCmNvbG5hbWVzKGV2X3BhcmFtX2RmKSA8LSBjKCJMb2NhdGlvbiIsICJTY2FsZSIsICJTaGFwZSIpCgojIEFkZCBhIG1pc3NpbmcgdmFsdWUgZm9yIEd1bWJlbCBzaGFwZQpldl9wYXJhbV9kZlsyLDNdIDwtIE5BCgojIERpc3BsYXkgYSBwcmV0dHkgdGFibGUKZXZfcGFyYW1fZGYgJT4lIGthYmxlKGNhcHRpb24gPSAiT3B0aW1hbCBQYXJhbWV0ZXJzIGZvciB0aGUgQ2FuZGlkYXRlIERpc3RyaWJ1dGlvbnMiLCBkaWdpdHMgPSAzKSAlPiUga2FibGVfc3R5bGluZygic3RyaXBlZCIsIGZ1bGxfd2lkdGggPSBGKSAlPiUga2FibGVfc3R5bGluZygpICU+JSBmb290bm90ZShnZW5lcmFsID0gIkVzdGltYXRlZCBVc2luZyBNYXhpbXVtIExpa2VsaWhvb2QiKQoKCmBgYAoKVG8gZXZhbHVhdGUgdGhlIG1vZGVsIGZpdCBtb3JlIHJpZ29yb3VzbHksIEkgY29tcGFyZWQgdGhlIEt1bGxiYWNrLUxlaWJsZXIgZGl2ZXJnZW5jZSBmb3IgZWFjaCB0aGVvcmV0aWNhbCBkaXN0cmlidXRpb24uCgpgYGB7cn0KIyBGaXJzdCwgZmluZCB0aGUgZGVuc2l0eSBvZiB0aGUgZGF0YQptM19kZW4gPSBoaXN0KHNtYWxsX2RmWywzXSwgYnJlYWtzID0gMjUsIGZyZXEgPSBGQUxTRSwgcGxvdCA9IEZBTFNFKQojID9oaXN0CiMgbTNfZGVuJGRlbnNpdHkKCiMgUmV3cml0ZSBtMiBhcyB0aGUgb3B0aW1hbCBwYXJhbWV0ZXJzIG9mIHNrZXcgbm9ybWFsCiMgc25fcGFyYW1zID0gbTIkcGFyCiMgc25fcGFyYW1zCgojIE5leHQgY29tcHV0ZSB0aGUgcHJvYmFiaWxpdHkgYXQgZWFjaCBwb2ludCBmb3IgdGhlIGZpdHRlZCBtb2RlbHMKIyMgU2tldy1ub3JtYWwKc2tuX2RlbiA9IGRzbm9ybShtM19kZW4kbWlkcywgbWVhbiA9IG0yJHBhclsxXSwgc2QgPSBtMiRwYXJbMl0sIHhpID0gbTIkcGFyWzNdKQojIyBHdW1iZWwKZ3VtYl9kZW4gPSBkZ3VtYmVsKG0zX2RlbiRtaWRzLCBsb2MgPSBndW1fcGFyYW0kbWxlWzFdLCBzY2FsZSA9IGd1bV9wYXJhbSRtbGVbMl0pCiMjIEdFVgpnZXZfZGVuID0gZGdldihtM19kZW4kbWlkcywgbG9jID0gZ2V2X3BhcmFtJG1sZVsxXSwgc2NhbGUgPSBnZXZfcGFyYW0kbWxlWzJdLCBzaGFwZSA9IGdldl9wYXJhbSRtbGVbM10pCgojIENhbGN1bGF0ZSB0aGUgSy1MIGRpdmVyZ2VuY2VzIGZvciBlYWNoCmtsX3NrbiA9IEtMRChtM19kZW4kZGVuc2l0eSwgc2tuX2RlbikKa2xfZ3VtYiA9IEtMRChtM19kZW4kZGVuc2l0eSwgZ3VtYl9kZW4pCmtsX2dldiA9IEtMRChtM19kZW4kZGVuc2l0eSwgZ2V2X2RlbikKCiMgQ29tYmluZSBpbnRvIGEgZGF0YSBmcmFtZQprbF9kZiA9IGFzLmRhdGEuZnJhbWUoY2JpbmQoa2xfc2tuJG1lYW4uc3VtLktMRCwga2xfZ3VtYiRtZWFuLnN1bS5LTEQsIGtsX2dldiRtZWFuLnN1bS5LTEQpKQoKcm93bmFtZXMoa2xfZGYpIDwtIGMoIk1lYW4gU3VtIEstTCBEaXZlcmdlbmNlIikKY29sbmFtZXMoa2xfZGYpIDwtIGMoIlNrZXctTm9ybWFsIiwgIkd1bWJlbCIsICJHRVYiKQoKIyBEaXNwbGF5IGEgcHJldHR5IHRhYmxlCmtsX2RmICU+JSBrYWJsZShjYXB0aW9uID0gIkNvbXBhcmluZyBLLUwgRGl2ZXJnZW5jZXMgQnkgTW9kZWwgRml0cyIsIGRpZ2l0cyA9IDIpICU+JSBrYWJsZV9zdHlsaW5nKCJzdHJpcGVkIiwgZnVsbF93aWR0aCA9IEYpICU+JSBrYWJsZV9zdHlsaW5nKCkgCmBgYAoKQmFzZWQgb24gdGhlIEstTCBEaXZlcmdlbmNlLCBpdCB3b3VsZCBzZWVtIHRvIG1ha2Ugc2Vuc2UgdG8gdXNlIHRoZSBnZW5lcmFsaXplZCBleHRyZW1lIHZhbHVlIGRpc3RyaWJ1dGlvbiwgaG93ZXZlciwgdGhlIHByb2JsZW0gd2l0aCBkb2luZyB0aGlzIGlzIHRoZSBmYWN0IHRoYXQgdGhpcyBkaXN0cmlidXRpb24gZG9lc24ndCBoYXZlIHN1cHBvcnQgb3ZlciB0aGUgZW50aXJlIHJlYWwgbGluZS4gTW9yZW92ZXIsIHRoZSBTa2V3LU5vcm1hbCBkaXN0cmlidXRpb24gZGlkIG5vdCB3b3JrIHdlbGwgd2hlbiBmaXR0aW5nIHRoZSBIaWRkZW4gTWFya292IE1vZGVsLiBUaGVyZWZvcmUsIHRoZSBHdW1iZWwgaXMgdXNlZCBpbiBmaXR0aW5nIHRoZSBITU0gYmVsb3cuCgojIyBITU0gQmFja2dyb3VuZCBhbmQgUmVzdWx0cwoKVGhlIG1vdGl2YXRpbmcgaWRlYSBiZWhpbmQgYSBIaWRkZW4gTWFya292IE1vZGVsIGlzIHRoYXQgdGhlcmUgYXJlIDIgdW5rbm93biBsYXRlbnQgc3RhdGVzICRrJCB0aGF0IGdlbmVyYXRlIHRoZSBkYXRhIHRoYXQgaXMgc2Vlbi4gKFRoZSByZWZlcmVuY2UgZm9yIHRoaXMgaW5mb3JtYXRpb24gaXMgZ2l2ZW4gaGVyZSBbQFN0ZXBoZW5zMjAxOF0pLiBUaGUgYWxnb3JpdGhtIGltcGxlbWVudGVkIGhlcmUgY29tcHV0ZXMgZm9yd2FyZHMgcHJvYmFiaWxpdGllcywgJFxhbHBoYV97dGt9ID0gXG1hdGhiYntQfShYXzEsIC4uLiAsIFhfdDsgWl90ID0gaykkLiBUbyBzdGFydCwgb25lIHNpbXBseSBtdWx0aXBsaWVzIGFuIGVxdWFsbHktd2VpZ2h0ZWQgcHJpb3IgJFxwaV9rID0gMC41JCBieSB0aGUgbGlrZWxpaG9vZCBvZiB0aGUgZGF0YSBnaXZlbiBlYWNoIHN0YXRlLCBnaXZlbiBieSAkXG1hdGhiYntQfShYXzEgfCBaXzEgPSBrJCkuIAoKVGhlIGxpa2VsaWhvb2QgZnVuY3Rpb24gZm9yIHRoZSAicmF0aW9uYWwiIHN0YXRlIChyZXByZXNlbnRlZCBieSB0aGUgbXVsdGl2YXJpYXRlIENBVmlhUiBtb2RlbCkgaXMgcmVwcmVzZW50ZWQgYnkgYSBub3JtYWwgZGlzdHJpYnV0aW9uIHdoZXJlYXMgdGhlIGxpa2VsaWhvb2QgZnVuY3Rpb24gZm9yIHRoZSAiaXJyYXRpb25hbCIgc3RhdGUgKHJlcHJlc2VudGVkIGJ5IHRoZSB1bml2YXJpYXRlIENBVmlhUiBtb2RlbCkgaXMgcmVwcmVzZW50ZWQgYnkgdGhlIEd1bWJlbCBkaXN0cmlidXRpb24uIEJvdGggdXNlIHRoZSBwYXJhbWV0ZXJzIGVzdGltYXRlZCBhYm92ZS4KCk5vdywgb25jZSB0aGUgJFxhbHBoYV8xJCB2YWx1ZSBpcyBjYWxjdWxhdGUsICRcYWxwaGFfMiQgaXMgY2FsY3VsYXRlZCBhcyBmb2xsb3dzLCB3aXRoIGEgc2ltaWxhciBwcm9jZXNzIGZvciBhbiBhcmJpdHJhcnkgdmFsdWUgJFxhbHBoYV90JC4KCiQkClxhbHBoYV8yID0gKFxhbHBoYV8xIFApX2sgXG1hdGhiYntQfShYXzIgfCBaXzIgPSBrKQokJAoKVGhlICRQJCBzeW1ib2wgY29ycmVzcG9uZHMgdG8gYSBzeW1tZXRyaWMgMngyIHRyYW5zaXRpb24gbWF0cml4IHdoZXJlIHRoZSBmaXJzdCByb3cgaXMgJCgwLjksIDAuMSkkIGFuZCB0aGUgc2Vjb25kIHJvdyBpcyAkKDAuMSwgMC45KSQuCgoKVG8gY29tcHV0ZSB0aGUgYmFja3dhcmRzIHByb2JhYmlsaXRpZXMsIHdlIGNvbXB1dGUgdGhlIGZvbGxvd2luZyAkXGJldGFfe3RrfSA9IFxtYXRoYmJ7UH0oWF97dCsxfSwgLi4uICwgWF9UOyBaX3QgPSBrKSQsIGFuZCB0aGVuIHRoZSBwb3N0ZXJpb3IgZGlzdHJpYnV0aW9uIGZvciBlYWNoIHN0YXRlICRaX3QkIGlzIGdpdmVuIGJ5IHRoZSBmb2xsb3dpbmc6CgokJApcbWF0aGJie1B9KFpfdCA9IGt8IFhfMSwgLi4uLCBYX1QpID0gXGFscGhhX3t0a30gXGJldGFfe3RrfSAvIFxzdW1fe2t9XGFscGhhX3t0a30gXGJldGFfe3RrfQokJAoKYGBge3J9CiMgIyBCZWxvdyBhcmUgdGhlIG9wdGltYWwgcGFyYW1ldGVycyBmb3IgdGhlIHNlY29uZCBtb2RlbAojIG5vcm1fcGFyYW1fZGYgPSBhcy5kYXRhLmZyYW1lKGNiaW5kKG1lYW4oc21hbGxfZGZbLDJdKSxzZChzbWFsbF9kZlssMl0pKSkKIyByb3duYW1lcyhub3JtX3BhcmFtX2RmKSA8LSBjKCJPcHRpbWFsIFBhcmFtZXRlcnMiKQojIGNvbG5hbWVzKG5vcm1fcGFyYW1fZGYpIDwtIGMoIk1lYW4iLCAiU3RhbmRhcmQgRGV2aWF0aW9uIikKIyAKIyAjIERpc3BsYXkgYSBwcmV0dHkgdGFibGUKIyBub3JtX3BhcmFtX2RmICU+JSBrYWJsZShjYXB0aW9uID0gIk9wdGltYWwgUGFyYW1ldGVycyBmb3IgdGhlIE5vcm1hbCBEaXN0cmlidXRpb24iLCBkaWdpdHMgPSAyKSAlPiUga2FibGVfc3R5bGluZygic3RyaXBlZCIsIGZ1bGxfd2lkdGggPSBGKSAlPiUga2FibGVfc3R5bGluZygpICU+JSBmb290bm90ZShnZW5lcmFsID0gIlRoZSBNZWFuIFdhcyBFc3RpbWF0ZWQgVXNpbmcgdGhlIFNhbXBsZSBNZWFuLCBTRCB3YXMgRXN0aW1hdGVkIFVzaW5nIFNhbXBsZSBTdGQuIERldi4iKQojIAojICMgc25fcGFyYW1zCiMgCiMgIyBEaXNwbGF5IHRoZSBvcHRpbWFsIHNrZXctbm9ybWFsIHBhcmFtZXRlcnMKIyBzbl9wYXJhbV9kZiA9IGFzLmRhdGEuZnJhbWUodChzbl9wYXJhbXMpKQojIHJvd25hbWVzKHNuX3BhcmFtX2RmKSA8LSBjKCJPcHRpbWFsIFBhcmFtZXRlcnMiKQojIGNvbG5hbWVzKHNuX3BhcmFtX2RmKSA8LSBjKCJMb2NhdGlvbiIsICJTY2FsZSIsICJTaGFwZSIpCiMgCiMgIyBEaXNwbGF5IGEgcHJldHR5IHRhYmxlCiMgc25fcGFyYW1fZGYgJT4lIGthYmxlKGNhcHRpb24gPSAiT3B0aW1hbCBQYXJhbWV0ZXJzIGZvciB0aGUgU2tldyBOb3JtYWwgRGlzdHJpYnV0aW9uIiwgZGlnaXRzID0gNCkgJT4lIGthYmxlX3N0eWxpbmcoInN0cmlwZWQiLCBmdWxsX3dpZHRoID0gRikgJT4lIGthYmxlX3N0eWxpbmcoKSAlPiUgZm9vdG5vdGUoZ2VuZXJhbCA9ICJFc3RpbWF0ZWQgVXNpbmcgTWF4aW11bSBMaWtlbGlob29kIikKIyAKIyAjIGd1bV9wYXJhbSRtbGUKIyAKIyAjIERpc3BsYXkgdGhlIG9wdGltYWwgR3VtYmVsIHBhcmFtZXRlcnMKIyBndW1fcGFyYW1fZGYgPSBhcy5kYXRhLmZyYW1lKHQoZ3VtX3BhcmFtJG1sZSkpCiMgcm93bmFtZXMoZ3VtX3BhcmFtX2RmKSA8LSBjKCJPcHRpbWFsIFBhcmFtZXRlcnMiKQojIGNvbG5hbWVzKGd1bV9wYXJhbV9kZikgPC0gYygiTG9jYXRpb24iLCAiU2NhbGUiKQojIAojICMgRGlzcGxheSBhIHByZXR0eSB0YWJsZQojIGd1bV9wYXJhbV9kZiAlPiUga2FibGUoY2FwdGlvbiA9ICJPcHRpbWFsIFBhcmFtZXRlcnMgZm9yIHRoZSBHdW1iZWwgRGlzdHJpYnV0aW9uIiwgZGlnaXRzID0gNCkgJT4lIGthYmxlX3N0eWxpbmcoInN0cmlwZWQiLCBmdWxsX3dpZHRoID0gRikgJT4lIGthYmxlX3N0eWxpbmcoKSAlPiUgZm9vdG5vdGUoZ2VuZXJhbCA9ICJFc3RpbWF0ZWQgVXNpbmcgTWF4aW11bSBMaWtlbGlob29kIikKIyAKIyAKIyAjIFRha2Ugb3V0IHRoZSBvcHRpbWFsIHBhcmFtZXRlcnMKIyBnZXZfcGFyYW1fZGYgPSBhcy5kYXRhLmZyYW1lKHQoZ2V2X3BhcmFtJG1sZSkpCiMgcm93bmFtZXMoZ2V2X3BhcmFtX2RmKSA8LSBjKCJPcHRpbWFsIFBhcmFtZXRlcnMiKQojIGNvbG5hbWVzKGdldl9wYXJhbV9kZikgPC0gYygiTG9jYXRpb24iLCAiU2NhbGUiLCAiU2hhcGUiKQojIAojICMgRGlzcGxheSBhIHByZXR0eSB0YWJsZQojIGdldl9wYXJhbV9kZiAlPiUga2FibGUoY2FwdGlvbiA9ICJPcHRpbWFsIFBhcmFtZXRlcnMgZm9yIHRoZSBHZW5lcmFsaXplZCBFeHRyZW1lIFZhbHVlIERpc3RyaWJ1dGlvbiIsIGRpZ2l0cyA9IDIpICU+JSBrYWJsZV9zdHlsaW5nKCJzdHJpcGVkIiwgZnVsbF93aWR0aCA9IEYpICU+JSBrYWJsZV9zdHlsaW5nKCkgJT4lIGZvb3Rub3RlKGdlbmVyYWwgPSAiRXN0aW1hdGVkIFVzaW5nIE1heGltdW0gTGlrZWxpaG9vZCIpCmBgYAoKCgoKYGBge3J9CiMgQ2xlYW4gb3V0IG9sZCB2YXJpYWJsZXMKIyBybShsaXN0PWxzKCkpCgojIFRoaXMgaXMgdGhlIHRydWUgbW9kZWwgdXNlZCBpbiB0aGUgc2ltdWxhdGlvbiBzdHVkeS4gV2Ugd29uJ3QgbmVlZCBpdC4KIyBzZXQuc2VlZCgxKQojIFQgPSAyMDAKIyBLID0gMgojIHNkPSAwLjQKIyBQID0gY2JpbmQoYygwLjksMC4xKSxjKDAuMSwwLjkpKQoKIyBTaW11bGF0ZSB0aGUgbGF0ZW50IChIaWRkZW4pIE1hcmtvdiBzdGF0ZXMKIyBBbHNvIG5vdCBuZWVkZWQuCiMgWiA9IHJlcCgwLFQpCiMgWlsxXSA9IDEKIyBmb3IodCBpbiAxOihULTEpKXsKIyAgIFpbdCsxXSA9IHNhbXBsZShLLCBzaXplPTEsIHByb2I9UFtaW3RdLF0pCiMgfQoKCiMgU2ltdWxhdGUgdGhlIGVtaXR0ZWQvb2JzZXJ2ZWQgdmFsdWVzCiMgWD0gcm5vcm0oVCxtZWFuPVosc2Q9c2QpCiMgWAoKIyBwbG90KFgsIG1haW49IlJlYWxpemF0aW9uIG9mIEhNTTsgbGF0ZW50IHN0YXRlcyBzaG93biBpbiByZWQiKQojIGxpbmVzKFosY29sPTIsbHdkPTIpCgojIEluc3RlYWQsIGxldCdzIHN1YnNldCBvdXIgZGF0YSBmcmFtZQojIHNtYWxsX3Rlc3QgPSB0ZXN0X2xvc3NbLGMoMSw1KV0KIyBjb2xTdW1zKHNtYWxsX3Rlc3QpCgojIFNldCBhIHZhbHVlIG9mIFQgYW5kIEsKVCA9IG5yb3coc21hbGxfZGYpCksgPSBuY29sKHNtYWxsX2RmKSAtIDEKCiMgc21hbGxfZGYKCiMgQXNzaWduIGEgdmFsdWUgb2YgUApQID0gY2JpbmQoYygwLjksMC4xKSxjKDAuMSwwLjkpKQoKIyBQbG90IHRoZXNlIGRhdGEKIyA/aGlzdAojIHBhcihtZnJvdz0gYygxLDIpKQojIGhpc3Qoc21hbGxfdGVzdFssMV0sIGJyZWFrcyA9IDI1KQojIGhpc3Qoc21hbGxfdGVzdFssMl0sIGJyZWFrcyA9IDI1KQojIAojICMgVHJhbnNmb3JtIHRoZSBkYXRhc2V0CiMgbG9nX3Rlc3QgPSBsb2coc21hbGxfdGVzdCkKIyAKIyAjIFBsb3QgdGhlIGxvZ3M/CiMgcGFyKG1mcm93PSBjKDEsMikpCiMgaD0gaGlzdChsb2dfdGVzdFssMV0sIGJyZWFrcyA9IDI1KQojICMgT3ZlcnNldCBhIGRlbnNpdHkgZnVuY3Rpb24KIyB4Zml0PC1zZXEobWluKGxvZ190ZXN0WywxXSksbWF4KGxvZ190ZXN0WywxXSksbGVuZ3RoPTQwKQojIHlmaXQ8LWRub3JtKHhmaXQsbWVhbj1tZWFuKGxvZ190ZXN0WywxXSksc2Q9c2QobG9nX3Rlc3RbLDFdKSkKIyB5Zml0IDwtIHlmaXQqZGlmZihoJG1pZHNbMToyXSkqbGVuZ3RoKGxvZ190ZXN0WywxXSkKIyBsaW5lcyh4Zml0LCB5Zml0LCBjb2w9ImJsdWUiLCBsd2Q9MikKIyAKIyAjIFJlcGVhdCB0aGUgc2FtZSB0aGluZwojIGg9IGhpc3QobG9nX3Rlc3RbLDJdLCBicmVha3MgPSAyNSkKIyAjIE92ZXJzZXQgYSBkZW5zaXR5IGZ1bmN0aW9uCiMgeGZpdDwtc2VxKG1pbihsb2dfdGVzdFssMl0pLG1heChsb2dfdGVzdFssMl0pLGxlbmd0aD00MCkKIyB5Zml0PC1kbm9ybSh4Zml0LG1lYW49bWVhbihsb2dfdGVzdFssMl0pLHNkPXNkKGxvZ190ZXN0WywyXSkpCiMgeWZpdCA8LSB5Zml0KmRpZmYoaCRtaWRzWzE6Ml0pKmxlbmd0aChsb2dfdGVzdFssMl0pCiMgbGluZXMoeGZpdCwgeWZpdCwgY29sPSJibHVlIiwgbHdkPTIpCiMgCiMgCiMgIyBGaW5kIHRoZSBtZWFucyBhbmQgU0RzCiMgdjEgPSByYmluZChtZWFuKGxvZ190ZXN0WywxXSksIHNkKGxvZ190ZXN0WywxXSkpCiMgCiMgIyBGaW5kIHRoZSBtZWFucyBhbmQgU0RzCiMgdjIgPSByYmluZChtZWFuKGxvZ190ZXN0WywyXSksIHNkKGxvZ190ZXN0WywyXSkpCiMgCiMgIyBTdG9yZSBhcyBhIGRhdGEgZnJhbWUKIyBzdW1fZGYgPSBhcy5kYXRhLmZyYW1lKGNiaW5kKHYxLHYyKSkKIyByb3duYW1lcyhzdW1fZGYpIDwtIGMoIk1lYW4iLCAiU0QiKQojIGNvbG5hbWVzKHN1bV9kZikgPC0gYygiTm8gQVIiLCAiU0FWIikKIyAKIyAjIEZvcm1hdCBuaWNlbHkKIyBzdW1fZGYgJT4lIGthYmxlKGNhcHRpb24gPSAiU3VtbWFyeSBTdGF0aXN0aWNzIGZvciB0aGUgTG9nIG9mIExvc3NlcyBmcm9tIEVhY2ggTW9kZWwiLCBkaWdpdHMgPSAyKSAlPiUga2FibGVfc3R5bGluZygic3RyaXBlZCIsIGZ1bGxfd2lkdGggPSBGKSAlPiUga2FibGVfc3R5bGluZygpCgojIGxvZ190ZXN0CgoKYGBgCgoKCgpgYGB7cn0KIyB0aGlzIGlzIHRoZSBmdW5jdGlvbiBQcihYX3QgfCBaX3Q9aykgZm9yIG91ciBleGFtcGxlCiMgVGhpcyBpcyB0aGUgZW1pc3Npb24gcHJvYmFiaWxpdHkgaW4gdGhlICJyYXRpb25hbCB3b3JsZCIsIG1vZGlmaWVkIGZvciB3aGV0aGVyIHdlIG1pc3MgcG9zaXRpdmUgb3IgbmVnYXRpdmUKZW1pdF9ub3JtID0gZnVuY3Rpb24ob2JzLG1lYW4sIHNkKXsgCiAgZG5vcm0ob2JzLCBtZWFuID0gbWVhbiwgc2QgPSBzZCkKICAjIGRub3JtKHgsbWVhbj1rLHNkPXNkKQp9CgojIEhlcmUgaXMgd2hlcmUgd2Ugd2lsbCBpbnB1dCBvdXIgZW1pc3Npb24gcHJvYmFiaWxpdGllcyBmb3IgYSBHRVYKZW1pdF9nZXYgPSBmdW5jdGlvbihvYnMsbG9jLCBzY2FsZSwgc2hhcGUpeyAKICBkZ2V2KG9icywgbG9jID0gbG9jLCBzY2FsZSA9IHNjYWxlLCBzaGFwZSA9IHNoYXBlKQp9CgojIFRoZSBHRVYgZG9lc24ndCBoYXZlIHN1cHBvcnQgb3ZlciBhbGwgb2YgdGhlIHJlYWwgbGluZSwgd2hpY2ggaXMgYSBwcm9ibGVtCmVtaXRfc24gPSBmdW5jdGlvbihvYnMsbG9jLCBzY2FsZSwgc2hhcGUpeyAKICBkc25vcm0ob2JzLCBtZWFuID0gbG9jLCBzZCA9IHNjYWxlLCB4aSA9IHNoYXBlKQp9CgojIExldCdzIHRyeSB0aGUgR3VtYmVsIGRpc3RyaWJ1dGlvbgplbWl0X2d1bWIgPSBmdW5jdGlvbihvYnMsbG9jLCBzY2FsZSl7IAogIGRndW1iZWwob2JzLCBsb2MgPSBsb2MsIHNjYWxlID0gc2NhbGUpCn0KCiMgc25fcGFyYW1fZGYKCiMgT3VyIHByaW9yIGlzIHRoYXQgYm90aCBzdGF0ZXMgYXJlIGVxdWFsbHkgbGlrZWx5LgpwcmlvciA9IGMoMC41LDAuNSkgI0Fzc3VtZWQgcHJpb3IgZGlzdHJpYnV0aW9uIG9uIFpfMQoKIyBUaGUgbWF0cml4IHdoZXJlIHdlIHN0b3JlIHRoZSBmb3J3YXJkcyBwcm9iYWJpbGl0aWVzCmFscGhhID0gbWF0cml4KG5yb3cgPSBULG5jb2w9SykKCgojIGZvcihrIGluIDE6Syl7IAojICAgYWxwaGFbMSxrXSA9IHByaW9yW2tdICogZW1pdChrLFhbMV0pCiMgfQoKIyBoZWFkKHNtYWxsX2RmKQojIG5vcm1fcGFyYW1fZGYkYFN0YW5kYXJkIERldmlhdGlvbmAKIyBnZXZfcGFyYW1fZGYkTG9jYXRpb24KCiMgc25fcGFyYW1fZGYkTG9jYXRpb24KZ3VtX3BhcmFtX2RmID0gZXZfcGFyYW1fZGZbMiwxOjJdCiMgZ3VtX3BhcmFtX2RmJExvY2F0aW9uCgojIEluaXRpYWxpemUgYWxwaGFbMSxdCmZvcihrIGluIDE6Syl7CiAgaWYgKGsgPT0gMSl7CiAgICAjIFRoaXMgaXMgdGhlIGVtaXNzaW9uIHByb2JhYmlsaXR5IGFzc3VtaW5nIG5vcm1hbGl0eQogICAgYWxwaGFbMSxrXSA9IHByaW9yW2tdICogZW1pdF9ub3JtKG9icyA9IHNtYWxsX2RmJFNQWVsxXSwgbWVhbiA9IG5vcm1fcGFyYW1fZGYkTWVhbiwgc2QgPSBub3JtX3BhcmFtX2RmJGBTdGFuZGFyZCBEZXZpYXRpb25gKQogIH0gZWxzZSBpZiAoayA9PSAyKXsKICAgICMgVGhpcyBpcyB0aGUgZW1pc3Npb24gcHJvYmFiaWxpdHkgYXNzdW1pbmcgR0VWCiAgICAjIGFscGhhWzEsa10gPSBwcmlvcltrXSAqIGVtaXRfZ2V2KG9icyA9IHNtYWxsX2RmJFNQWVsxXSwgbG9jID0gZ2V2X3BhcmFtX2RmJExvY2F0aW9uLCBzY2FsZSA9IGdldl9wYXJhbV9kZiRTY2FsZSwgc2hhcGUgPSBnZXZfcGFyYW1fZGYkU2hhcGUpCiAgICAjIFRoaXMgaXMgdGhlIGVtaXNzaW9uIHByb2JhYmlsaXR5IGFzc3VtaW5nIFNOCiAgICAjIGFscGhhWzEsa10gPSBwcmlvcltrXSAqIGVtaXRfc24ob2JzID0gc21hbGxfZGYkU1BZWzFdLCBsb2MgPSBzbl9wYXJhbV9kZiRMb2NhdGlvbiwgc2NhbGUgPSBzbl9wYXJhbV9kZiRTY2FsZSwgc2hhcGUgPSBzbl9wYXJhbV9kZiRTaGFwZSkKICAgICMgVGhpcmQgdGltZSBpcyB0aGUgY2hhcm0uLi5hc3N1bWUgYSBHdW1iZWwKICAgIGFscGhhWzEsa10gPSBwcmlvcltrXSAqIGVtaXRfZ3VtYihvYnMgPSBzbWFsbF9kZiRTUFlbMV0sIGxvYyA9IGd1bV9wYXJhbV9kZiRMb2NhdGlvbiwgc2NhbGUgPSBndW1fcGFyYW1fZGYkU2NhbGUpCiAgfSBlbHNlIHsKICAgIHByaW50KCJrIHNob3VsZCBub3QgYmUgZ3JlYXRlciB0aGFuIDIiKQogIH0KfQoKIyBoZWFkKGFscGhhKQojIHNtYWxsX2RmJFNQWVsxXQojIGFscGhhWzEsXSAlKiUgUAoKCiMgRm9yd2FyZCBhbGdvcml0aG0KZm9yKHQgaW4gMTooVC0xKSl7CiAgIyBGaW5kIHRoZSB2YWx1ZSBvZiBtIGF0IGVhY2ggc3RlcAogIG0gPSBhbHBoYVt0LF0gJSolIFAKICAjIExvb3AgdGhyb3VnaCB0byB1cGRhdGUgbGV2ZWxzIG9mIGFscGhhCiAgZm9yKGsgaW4gMTpLKXsKICAgICMgYWxwaGFbdCsxLGtdID0gbVtrXSplbWl0KGssWFt0XSkgd2hhdCBJIGhhZAogICAgIyBhbHBoYVt0KzEsa10gPSBtW2tdKmVtaXQoayxYW3QrMV0pIG9ubGluZQogICAgaWYgKGsgPT0gMSl7CiAgICAgICMgYWxwaGFbdCsxLGtdID0gbVtrXSplbWl0KGssWFt0KzFdKSBvbmxpbmUKICAgICAgYWxwaGFbdCsxLGtdID0gbVtrXSplbWl0X25vcm0ob2JzID0gc21hbGxfZGYkU1BZW3QrMV0sIG1lYW4gPSBub3JtX3BhcmFtX2RmJE1lYW4sIHNkID0gbm9ybV9wYXJhbV9kZiRgU3RhbmRhcmQgRGV2aWF0aW9uYCkKICAgIH0gZWxzZSBpZiAoayA9PSAyKXsKICAgICAgIyBBc3N1bWluZyBhIEdFVgogICAgICAjIGFscGhhW3QrMSxrXSA9IG1ba10qZW1pdF9nZXYob2JzID0gc21hbGxfZGYkU1BZW3QrMV0sIGxvYyA9IGdldl9wYXJhbV9kZiRMb2NhdGlvbiwgc2NhbGUgPSBnZXZfcGFyYW1fZGYkU2NhbGUsIHNoYXBlID0gZ2V2X3BhcmFtX2RmJFNoYXBlKQogICAgICAjIEFzc3VtaW5nIGEgc2tldy1ub3JtYWwKICAgICAgIyBhbHBoYVt0KzEsa10gPSBtW2tdKmVtaXRfc24ob2JzID0gc21hbGxfZGYkU1BZW3QrMV0sIGxvYyA9IHNuX3BhcmFtX2RmJExvY2F0aW9uLCBzY2FsZSA9IHNuX3BhcmFtX2RmJFNjYWxlLCBzaGFwZSA9IHNuX3BhcmFtX2RmJFNoYXBlKQogICAgICAjIEFzc3VtaW5nIGEgR3VtYmVsCiAgICAgIGFscGhhW3QrMSxrXSA9IG1ba10qZW1pdF9ndW1iKG9icyA9IHNtYWxsX2RmJFNQWVt0KzFdLCBsb2MgPSBndW1fcGFyYW1fZGYkTG9jYXRpb24sIHNjYWxlID0gZ3VtX3BhcmFtX2RmJFNjYWxlKQogICAgfSBlbHNlIHsKICAgICAgcHJpbnQoImsgc2hvdWxkIG5vdCBiZSBncmVhdGVyIHRoYW4gMiIpCiAgICB9CiAgICAjIGFscGhhW3QrMSxrXSA9IG1ba10qZW1pdChvYnMgPSBsb2dfdGVzdFt0KzEsa10sIG1lYW4gPSBzdW1fZGZbMSxrXSwgc2QgPSBzdW1fZGZbMixrXSkKICB9Cn0KCiMgZW1pdF9nZXYob2JzID0gc21hbGxfZGYkU1BZWzJdLCBsb2MgPSBnZXZfcGFyYW1fZGYkTG9jYXRpb24sIHNjYWxlID0gZ2V2X3BhcmFtX2RmJFNjYWxlLCBzaGFwZSA9IGdldl9wYXJhbV9kZiRTaGFwZSkKIyBlbWl0X3NuKG9icyA9IHNtYWxsX2RmJFNQWVsyXSwgbG9jID0gc25fcGFyYW1fZGYkTG9jYXRpb24sIHNjYWxlID0gc25fcGFyYW1fZGYkU2NhbGUsIHNoYXBlID0gc25fcGFyYW1fZGYkU2hhcGUpCiMgc25fcGFyYW1fZGYkTG9jYXRpb24KIyBzbl9wYXJhbV9kZiRTY2FsZQojIHNuX3BhcmFtX2RmJFNoYXBlCgojIGRzbm9ybShzbWFsbF9kZiRTUFlbMl0sIG1lYW4gPSBzbl9wYXJhbV9kZiRMb2NhdGlvbiwgc2QgPSBzbl9wYXJhbV9kZiRTY2FsZSwgeGkgPSBzbl9wYXJhbV9kZiRTaGFwZSkKIyBoaXN0KHJzbm9ybSgxMDAwMCwgbWVhbiA9IHNuX3BhcmFtX2RmJExvY2F0aW9uLCBzZCA9IHNuX3BhcmFtX2RmJFNjYWxlLCB4aSA9IHNuX3BhcmFtX2RmJFNoYXBlKSwgeGxpbSA9IGMoLTIsMCkpCgojIFRyeSBpdCB3aXRoIGEgZ3VtYmVsCiMgZGd1bWJlbChzbWFsbF9kZiRTUFlbM10sIGxvYyA9IGd1bV9wYXJhbV9kZiRMb2NhdGlvbiwgc2NhbGUgPSBndW1fcGFyYW1fZGYkU2NhbGUpCgojIHNtYWxsX2RmJFNQWVsyXQoKIyBhbHBoYQoKYGBgCgoKYGBge3J9CiMgSW5pdGFsaXplIGEgYmV0YSBtYXRyaXgKYmV0YSA9IG1hdHJpeChucm93ID0gVCxuY29sPUspCgojIEluaXRpYWxpemUgYmV0YQpmb3IoayBpbiAxOkspewogIGJldGFbVCxrXSA9IDEKfQoKIyBCYWNrd2FyZHMgYWxnb3JpdGhtCmZvcih0IGluIChULTEpOjEpewogIGZvcihrIGluIDE6Syl7CiAgICAjIE1vZGlmeSB0aGUgdmFsdWUgb2YgYmV0YQogICAgIyBiZXRhW3Qsa10gPSBzdW0oYmV0YVt0KzEsXSpQW2ssXSplbWl0KDE6SyxYW3QrMV0pKQogICAgIyBiZXRhW3Qsa10gPSBzdW0oYmV0YVt0KzEsXSpQW2ssXSplbWl0KG9icyA9IGxvZ190ZXN0W3QrMSxrXSwgbWVhbiA9IHN1bV9kZlsxLGtdLCBzZCA9IHN1bV9kZlsyLGtdKSkKICAgICMgYmV0YVt0LGtdID0gc3VtKGJldGFbdCsxLF0qUFtrLF0qZW1pdCgxOkssWFt0KzFdKSkKICAgIGlmIChrID09IDEpewogICAgICAjIEhlcmUncyB3aGF0IHdhcyBvbmxpbmUKICAgICAgIyBiZXRhW3Qsa10gPSBzdW0oYmV0YVt0KzEsXSpQW2ssXSplbWl0KDE6SyxYW3QrMV0pKQogICAgICAjIEZpbmQgdGhlIHZhbHVlcyBzZXBhcmF0ZWx5CiAgICAgIHYxID0gZW1pdF9ub3JtKG9icyA9IHNtYWxsX2RmJFNQWVt0KzFdLCBtZWFuID0gbm9ybV9wYXJhbV9kZiRNZWFuLCBzZCA9IG5vcm1fcGFyYW1fZGYkYFN0YW5kYXJkIERldmlhdGlvbmApCiAgICAgIHYyID0gZW1pdF9ndW1iKG9icyA9IHNtYWxsX2RmJFNQWVt0KzFdLCBsb2MgPSBndW1fcGFyYW1fZGYkTG9jYXRpb24sIHNjYWxlID0gZ3VtX3BhcmFtX2RmJFNjYWxlKQogICAgICBiZXRhW3Qsa10gPSBzdW0oYmV0YVt0KzEsXSpQW2ssXSpjKHYxLCB2MikpCiAgICB9IGVsc2UgaWYgKGsgPT0gMil7CiAgICAgICMgSGVyZSdzIHdoYXQgd2FzIG9ubGluZQogICAgICAjIEZpbmQgdGhlIHZhbHVlcyBzZXBhcmF0ZWx5CiAgICAgIHYxID0gZW1pdF9ub3JtKG9icyA9IHNtYWxsX2RmJFNQWVt0KzFdLCBtZWFuID0gbm9ybV9wYXJhbV9kZiRNZWFuLCBzZCA9IG5vcm1fcGFyYW1fZGYkYFN0YW5kYXJkIERldmlhdGlvbmApCiAgICAgIHYyID0gZW1pdF9ndW1iKG9icyA9IHNtYWxsX2RmJFNQWVt0KzFdLCBsb2MgPSBndW1fcGFyYW1fZGYkTG9jYXRpb24sIHNjYWxlID0gZ3VtX3BhcmFtX2RmJFNjYWxlKQogICAgICBiZXRhW3Qsa10gPSBzdW0oYmV0YVt0KzEsXSpQW2ssXSpjKHYxLCB2MikpCiAgICB9IGVsc2UgewogICAgICBwcmludCgiayBzaG91bGQgbm90IGJlIGdyZWF0ZXIgdGhhbiAyIikKICAgIH0KICB9Cn0KCgoKCmBgYAoKCmBgYHtyfQojIExhc3RseSwgd2UgbmVlZCB0byBzb2x2ZSBmb3IgdGhlIHBvc3RlcmlvcgphYiA9IGFscGhhKmJldGEKcHJvYiA9IGFiL3Jvd1N1bXMoYWIpCiMgcm93U3Vtcyhwcm9iKQojIHByb2IKCnBsb3QocHJvYlssMl0sdHlwZT0ibCIseWxpbT1jKDAsMSksIG1haW49IkNoYW5jZSB0aGUgV29ybGQgaXMgaW4gYW4gSXJyYXRpb25hbCBTdGF0ZSIsbHdkPTIseWxhYj0iUG9zdGVyaW9yIFByb2JhYmlsaXR5IikKIyBsaW5lcyhaPT0yLGNvbD0yLGx3ZD0yKQpgYGAKCmBgYHtyfQoKIyBCb2x0IG9uIGFuIE5BCm5vcm1fcGFyYW1fZGYyID0gY2JpbmQobm9ybV9wYXJhbV9kZiwgTkEpCiMgUmVuYW1lIHJvd3MgYW5kIGNvbHVtbnMKcm93bmFtZXMobm9ybV9wYXJhbV9kZjIpIDwtIGMoIk5vcm1hbCIpCmNvbG5hbWVzKG5vcm1fcGFyYW1fZGYyKSA8LSBjKCJMb2NhdGlvbiIsICJTY2FsZSIsICJTaGFwZSIpCgojIENvbWJpbmUgaW50byBhbiBvcHRpbWFsIHBhcmFtZXRlciBkZgpvcHRfcGFyYW1fZGYgPSByYmluZChub3JtX3BhcmFtX2RmMiwgZXZfcGFyYW1fZGYpCm9wdF9wYXJhbV9kZiRMb2NhdGlvbgpvcHRfcGFyYW1fZGYKCmFiYyA9IG9wdF9wYXJhbV9kZltjKCJOb3JtYWwiKSxdCmFiYyRMb2NhdGlvbgpgYGAKClRoZSBpbnRlcnByZXRhdGlvbiBvZiB0aGlzIGFib3ZlIGdyYXBoIHNlZW1zIHF1aXRlIGNsZWFyIGF0IGZpcnN0IGJsdXNoIC0gdGhlICJoaWRkZW4iIHN0YXRlIG9mIHRoZSB3b3JsZCB0aHJvdWdob3V0IDIwMDggaXMgaW5kZWVkIHRoZSAiaXJyYXRpb25hbCIgb25lLCBtYXJrZWQgYnkgdGhlIHJlbGF0aXZlIHN1Y2Nlc3Mgb2YgdGhlIHVuaXZhcmlhdGUgQ0FWaWFSIG1vZGVsLiBBcyBwZXJoYXBzIHdpdGggYWxsIHJlc2VhcmNoLCB0aGlzIHdvcmsgZ2VuZXJhdGVzIG1hbnkgbW9yZSBxdWVzdGlvbnMgdGhhbiBpdCBhbnN3ZXJzLiBUaGVyZSBhcmUgc2V2ZXJhbCBuZXh0IHN0ZXBzIHRoYXQgYXJlIHdvcnRoIGV4cGxvcmluZy4KCi0gQWRkaW5nIG1vcmUgbGFnZ2VkIHRlcm1zIGludG8gdGhlIEhNTSwgb3IgYXQgbGVhc3QgdGlua2VyaW5nIHdpdGggdGhlIHRyYW5zaXRpb24gcHJvYmFiaWxpdHkgdG8gdW5kZXJzdGFuZCB0aGUgc2Vuc2l0aXZpdHkgb2YgdGhlc2UgcGFyYW1ldGVycyB0byB0aGUgb3V0Y29tZQotIEV4cGxvcmluZyB3aGF0IGhhcHBlbnMgaWYgdGhlIEhNTSB3ZXJlIGZpdCB0byBhbGwgOCBjYW5kaWRhdGUgbW9kZWxzLCBvciB1c2luZyBhIE5ldXJhbCBOZXR3b3JrIG9yIFJhbmRvbSBGb3Jlc3QgdG8gZmluZCB0aGUgaGlkZGVuIHN0YXRlCi0gQ29uc2lkZXJpbmcgdGhlIGltcGxpY2l0IGFzc3VtcHRpb24gdGhhdCB0aGVzZSBmb3JlY2FzdHMgYXJlIGJhc2VkIG9uIGFuIGFzeW1tZXRyaWMgbG9zcyBmdW5jdGlvbiAoc2VlIHRoZSBBcHBlbmRpeCksIGFuZCBmaW5kaW5nIGEgd2F5IHRvIHdlaWdoIHRoZSBjb25zaWRlcmF0aW9uIHRoYXQgYW4gb3ZlcnByZWRpY3Rpb24gaXMgYSBmYWlybHkgY2xlYXIgaW5kaWNhdGlvbiB0aGF0IHRoZSB3b3JsZCBpcyBub3QgaW4gdGhhdCBzdGF0ZQoKIyMgQ2hhbmdlcG9pbnQgRGV0ZWN0aW9uCgpUaGUgc2Vjb25kIHF1ZXN0aW9uIGlzIHRvIHVuZGVyc3RhbmQgc2hpZnRzIGluIHRoZSBlY29ub215IHVzaW5nIGEgY2hhbmdlcG9pbnQgZGV0ZWN0aW9uIGFsZ29yaXRobToKCjEuIFVzaW5nIGEgc2V0IG9mIEVURnMsIHBlcmZvcm0gUHJpbmNpcGFsIENvbXBvbmVudCBBbmFseXNpcyBhdCAkVCQgbWFueSBwb2ludHMgZm9yICRNJCBtYW55IGZhY3RvcnMgLSAkZl97bSx0fSQKMi4gQXQgZWFjaCB0aW1lIHBvaW50LCBhZGQgdGhlIHZlY3RvcnMgdG9nZXRoZXIgdG8gZ2V0IGEgcmVzdWx0YW50OiAkXHN1bV97bT0xfV5NIGZfe20sdH0gPSByX3QkLCBnaXZpbmcgJHJfMSwgcl8yLCAuLi4sIHJfVCQuCjMuIFN0YXJ0aW5nIHdpdGggYW4gYXJiaXRyYXJ5IHJlZmVyZW5jZSBwb2ludCAkdF8wJCB3aXRoIGFzc29jaWF0ZWQgJHJfMCQgcmVzdWx0YW50LCBtZWFzdXJlIHRoZSBhbmdsZSBiZXR3ZWVuIHJlc3VsdGFudHMgY2FsY3VsYXRlZCBhdCBkaWZmZXJlbnQgdGltZSBzdGVwcyAkcl97dH0kCgokJApcdGhldGFfdCA9IFxhcmNjb3MgXGxlZnQoXGZyYWN7cl97MH0gXGNkb3Qgcl97dH19e3x8cl97MH18fCAgfHxyX3t0fXx8fSBccmlnaHQpCiQkCgpUaGUgYW5nbGUgJFx0aGV0YSQgY291bGQgYmUgcGxvdHRlZCBvdmVyIHRpbWUsIGFuZCBjaGFuZ2Vwb2ludHMgY291bGQgYmUgZGV0ZWN0ZWQgdXNpbmcgTW9udGUgQ2FybG8gc2ltdWxhdGlvbiwgYmVjYXVzZSBQQ0EgdHJhbnNmb3JtYXRpb25zIGFyZSBub24tbGluZWFyLCBzbyBjYWxjdWxhdGluZyBhbiBhbmFseXRpY2FsIGRlbnNpdHkgZnJvbSB0aGUgdHJhbnNmb3JtZWQgZGF0YSBpcyBpbnRyYWN0YWJsZS4gTW9yZW92ZXIsIHRoZSBkYXRhIGZlZCBpbnRvIHRoZSBQQ0EgdHJhbnNmb3JtYXRpb24gaXMgbm9uLW5vcm1hbCwgd2hpY2ggZnVydGhlciBzdXBwb3J0cyB0aGUgbm90aW9uIG9mIHVzaW5nIE1vbnRlIENhcmxvIHNpbXVsYXRpb24gdG8gZXN0YWJsaXNoIHJlYXNvbmFibGUgZXN0aW1hdGVzIG9mIHVuY2VydGFpbnR5IGZvciBkZXRlY3RlZCBjaGFuZ2Vwb2ludHMuIEFzIHdpdGggdGhlIGZpcnN0IGxpbmUgb2YgcmVhc29uaW5nLCB0aGVyZSB3b3VsZCBjZXJ0YWlubHkgYmUgaW50ZXJlc3RpbmcgY2hhbGxlbmdlcywgcGFydGljdWxhcmx5IGluIGNyZWF0aW5nIGNyaXNwIG51bGwgYW5kIGFsdGVybmF0aXZlIGh5cG90aGVzZXMuIAoKCiMjIERhdGEgVXNlZAoKVGhlIHJlc3BvbnNlIHZhcmlhYmxlIHVzZWQgaW4gdGhpcyBhbmFseXNpcyBpcyBTUFksIHdoaWNoIGlzIGFuIGV4Y2hhbmdlLXRyYWRlZCBmdW5kIHRoYXQgYWltcyB0byB0cmFjayB0aGUgcGVyZm9ybWFuY2Ugb2YgdGhlIFMmUCA1MDAsIHdoaWNoIGlzIGRpc2N1c3NlZCBhYm92ZS4gSXQgaXMgYnJvYWRseSB1c2VkIGFzIGEgYmVsbHdldGhlciBvZiB0aGUgVS5TLiBlY29ub215LCBhbmQgaGFzIHRoZSBhZHZhbnRhZ2Ugb2YgYXZvaWRpbmcgc3Vydml2b3JzaGlwIGJpYXMgLSB3aGlsZSBhbiBpbmRpdmlkdWFsIHN0b2NrIG1pZ2h0IGdvIGJhbmtydXB0IG9yIG1lcmdlIHdpdGggYW5vdGhlciwgaXQgaXMgcmVhc29uYWJsZSB0byBhc3N1bWUgdGhhdCB0aGVzZSBpc3N1ZXMgZG8gbm90IGFwcGx5IHdpdGggYW4gRVRGLiAKCkZvbGxvd2luZyB0aGlzIGxvZ2ljLCB0aGVyZSBhcmUgc2V2ZXJhbCBjbGFzc2VzIG9mIHJlc3BvbnNlIHZhcmlhYmxlcyB1c2VkIGluIHRoaXMgYW5hbHlzaXMuIFRoZSBmaXJzdCBncm91cCBpcyBhIHNldCBvZiBVLlMuIHNlY3RvciBFVEZzIG9idGFpbmVkIGZyb20gU2Vla2luZyBBbHBoYSBbQFNlZWtpbmdBbHBoYTIwMjBdLiBBcyB3aXRoIHRoZSByZXNwb25zZSB2YXJpYWJsZSwgdGhlc2UgRVRGcyB3ZXJlIHB1YmxpY2x5IHRyYWRlZCB0aHJvdWdob3V0IHRoZSBHcmVhdCBSZWNlc3Npb24gb2YgMjAwOC4KCmEuIFV0aWxpdGllcyAoWExVKQpiLiBDb25zdW1lciBTdGFwbGVzIChYTFApCmMuIEhlYWx0aGNhcmUgKFhMVikKZC4gVGVjaG5vbG9neSAoWExLKQplLiBDb25zdW1lciBEaXNjcmV0aW9uYXJ5IChYTFkpCmYuIEluZHVzdHJpYWwgKFhMSSkKZy4gRmluYW5jaWFsIFNlcnZpY2VzIChYTEYpCmguIEJhc2ljIE1hdGVyaWFscyAoWExCKQppLiBFbmVyZ3kgKFhMRSkKCgpUaGUgc2Vjb25kIGdyb3VwIGZvciB0aGlzIGFuYWx5c2lzIGlzIGJvbmQgRVRGcy4gTGlrZSB0aGUgcHJldmlvdXMgdHdvIGdyb3VwcywgdGhlc2UgRVRGcyBwb3RlbnRpYWxseSBjb250YWluIGZvcndhcmQtbG9va2luZyBpbmZvcm1hdGlvbiBhYm91dCB0aGUgc3RvY2sgbWFya2V0LiBUaGVzZSBFVEZzIHdlcmUgY2hvc2VuIGJlY2F1c2UgdGhleSB3ZXJlIHRoZSBmaXJzdCBmaXhlZC1pbmNvbWUgRVRGcyBhdmFpbGFibGUgaW4gdGhlIFVuaXRlZCBTdGF0ZXMsIGFuZCBoYWQgZW5vdWdoIGhpc3RvcnkgZm9yIHRoaXMgcGFwZXIgW0BOQTIwMTddLgoKYS4gaVNoYXJlcyAxLTMgWWVhciBUcmVhc3VyeSBCb25kIEZ1bmQgKFNIWSkKYi4gaVNoYXJlcyA3LTEwIFllYXIgVHJlYXN1cnkgQm9uZCBGdW5kIChJRUYpCmMuIGlTaGFyZXMgMjArIFllYXIgVHJlYXN1cnkgQm9uZCBGdW5kIChUTFQpCmQuIGlTaGFyZXMgaUJveHggJCBJbnZlc3RtZW50IEdyYWRlIENvcnBvcmF0ZSBCb25kIEVURiAoTFFEKQoKIyMgUmVzdWx0cwoKCgpgYGB7cn0KIyBUaGlzIGNvZGUgYmVsb3cgaXMgZm9yIHVzZSBpbiB0aGUgQ0FWaWFSIHNlY3Rpb25zLgoKcm0obGlzdCA9IGxzKCkpCmBgYAoKYGBge3J9CiMgSGVyZSBpcyBjb2RlIHRoYXQgSSdsbCB3cmFwIHNvbWUgcGFydHMgaW4gdG8gYXZvaWQgc3VwZXJmbHVvdXMgb3V0cHV0CnF1aWV0IDwtIGZ1bmN0aW9uKHgpIHsgCiAgc2luayh0ZW1wZmlsZSgpKSAKICBvbi5leGl0KHNpbmsoKSkgCiAgaW52aXNpYmxlKGZvcmNlKHgpKSAKfSAKYGBgCgoKYGBge3J9CiMnIFRoaXMgaXMgYSBmdW5jdGlvbiB3aGljaCBwdWxscyBkYXRhIGZvciB1c2UgaW4gdGhlIENBVmlhUiBtb2RlbAojJwojJyBAcGFyYW0gc3ltYm9sIC0gc3ltYm9sIHRvIHB1bGwKIycgQHBhcmFtIGNvbXBsX2Nhc2UgLSBkZWZhdWx0cyB0byB0cnVlLi4ub25seSBpbmNsdWRlcyBjb21wbGV0ZSBjYXNlcyBpbiB0aGUgZGF0YQojJyBAcGFyYW0gYWRqX2Nsb3NlIC0gdXNlIGFkanVzdGVkIGNsb3NpbmcgcHJpY2VzLiBEZWZhdWx0IGlzIHllcy4KIycgQHBhcmFtIGxvZ19yZXR1cm4gLSB1c2UgbG9nIHJldHVybj8gRGVmYXVsdCBpcyB5ZXMuCiMnCiMnIEByZXR1cm4gLSBhIGRhdGEgZnJhbWUgd2hpY2ggY2FuIGJlIGZlZCBpbnRvIGxhdGVyIGZ1bmN0aW9ucwojJyBAZXhwb3J0CiMnCiMnIEBleGFtcGxlcyAtIGRhdGFfcHVsbCgiU1BZIikKZGF0YV9wdWxsID0gZnVuY3Rpb24oc3ltYm9sLCBjb21wbF9jYXNlID0gMSwgYWRqX2Nsb3NlID0gMSwgbG9nX3JldHVybiA9IDEsIHN0YXJ0X2RhdGUgPSAiMTkwMC0wMS0wMSIsIGVuZF9kYXRlID0gU3lzLkRhdGUoKSl7CiAgIyBQdWxsIGluIGRhdGEgZnJvbSBxdWFudG1vZAogIHJlc3BvbnNlX3B1bGwgPSBnZXRTeW1ib2xzKHN5bWJvbCwgYXV0by5hc3NpZ24gPSBGQUxTRSwgZnJvbSA9IHN0YXJ0X2RhdGUsIHRvID0gZW5kX2RhdGUpCiAgIyBHZXQgYWRqdXN0ZWQgY2xvc2luZyBwcmljZQogIGlmIChhZGpfY2xvc2UgPT0gVFJVRSl7CiAgICBkZiA9IEFkKHJlc3BvbnNlX3B1bGwpCiAgfSBlbHNlIHsKICAgIGRmID0gQ2wocmVzcG9uc2VfcHVsbCkKICB9CiAgIyBSZXR1cm4gY29tcGxldGUgY2FzZXMgb25seSAKICBpZiAoY29tcGxfY2FzZSA9PSBUUlVFKXsKICAgIGRmID0gZGZbY29tcGxldGUuY2FzZXMoZGYpLCBdCiAgfSBlbHNlewogICAgZGYgPSBkZgogIH0KICAjIENhbGN1bGF0ZSBsb2cgcmV0dXJuIG9mIGRhdGEKICBpZiAobG9nX3JldHVybiA9PSBUUlVFKXsKICAgIGxyID0gbG9nKGRmWywxXS9zaGlmdChkZlssMV0sIDEsIHR5cGUgPSAibGFnIikpCiAgICAjIENvbWJpbmUgZGF0YQogICAgZGZfb3V0ID0gY2JpbmQoZGYsIGxyKQogICAgIyBSZW5hbWUgdGhlIGRhdGEgCiAgICBjb2xuYW1lcyhkZl9vdXQpIDwtIGMoc3ltPXN5bWJvbCwgcGFzdGUwKHN5bWJvbCwgIl9sb2dfcmV0dXJuIikpCiAgfSBlbHNlewogICAgZGZfb3V0ID0gZGYKICB9CiAgIyBSZXR1cm4gZGF0YQogIHJldHVybihkZl9vdXQpCn0KCgpgYGAKCmBgYHtyfQojJyBQdWxsIHRoZSBkYXRhIGFuZCBydW4gdGhlIENBVmlhUiBmdW5jdGlvbiBvbiBpdAojJwojJyBAcGFyYW0gaW5wdXRfZGF0YSAtIGRhdGEgdG8gdXNlIGluIHRoZSBmdW5jdGlvbgojJyBAcGFyYW0gcmFuZ2VfZGF0YSAtIHJhbmdlIG9mIHRoZSBkYXRhIHRvIHVzZQojJwojJyBAcmV0dXJuIC0gYSBsaXN0IG9mIHZhbHVlcyBmcm9tIHRoZSBjYXZpYXIgZnVuY3Rpb24KIycgQGV4cG9ydAojJwojJyBAZXhhbXBsZXMgLSBjYXZpYXJfcHVsbChzcHkpCmNhdmlhcl9wdWxsID0gZnVuY3Rpb24oaW5wdXRfZGF0YSwgcmFuZ2VfZGF0YSA9ICgyOmRpbShpbnB1dF9kYXRhKVsxXSkpewogICMgUnVuIHRoZSBjYXZpYXIgZGF0YQogIGNhdmlhciA8LSBjYXZpYXJPcHRpbShpbnB1dF9kYXRhW3JhbmdlX2RhdGEsMl0pCiAgcmV0dXJuKGNhdmlhcikKfQoKYGBgCgoKYGBge3J9CiMnIEZ1bmN0aW9uIGZvciBwcm9kdWNpbmcgcm9sbGluZyBwcmVkaWN0aW9ucwojJyBNb2RlbCAxID0gU3ltbWV0cmljIEFic29sdXRlIFZhbHVlLCAyID0gQXN5bW1ldHJpYyBzbG9wZSwgMyA9IEluZGlyZWN0IEdBUkNILCA0ID0gQWRhcHRpdmUKIycKIycgQHBhcmFtIGlucHV0X2RhdGEgLSBpbnB1dCBkYXRhIGZyb20gdGhlIHByZXZpb3VzIGZ1bmN0aW9uCiMnIEBwYXJhbSByYW5nZV9kYXRhIC0gcmFuZ2Ugb2YgdGhlIGRhdGEgdG8gY29uc2lkZXIKIycgQHBhcmFtIG5mY3N0IC0gbnVtYmVyIG9mIGZvcmVjYXN0cyB0byBtYWtlCiMnIEBwYXJhbSBtb2RlbCAtIG1vZGVsIHRvIHVzZSAoaW50ZWdlcnMgMSB0aHJvdWdoIDQpLiBEZWZhdWx0cyB0byAxLiAKIycgQHBhcmFtIGxldmVsIC0gbGV2ZWwgb2Ygc2lnbmlmaWNhbmNlIHRvIHVzZS4KIycgQHBhcmFtIEcgLSBhcmd1bWVudCBmb3IgdGhlIGsgcGFyYW1ldGVyIGluIHRoZSA0dGggbW9kZWwgKGFkYXB0aXZlKS4gRGVmYXVsdCBpcyA1CiMnCiMnIEByZXR1cm4gLSBhbiB4dHMgb2JqZWN0IHdoaWNoIGNvbnRhaW5zIHJvbGxpbmcgQ0FWaWFSIHByZWRpY3Rpb25zCiMnIEBleHBvcnQKIycKIycgQGV4YW1wbGVzIC0gcm9sbGluZ19wcmVkaWN0aW9ucyhzcHksIG5mY3N0ID0gMjIpCnJvbGxpbmdfcHJlZGljdGlvbnMgPSBmdW5jdGlvbihpbnB1dF9kYXRhLCByYW5nZV9kYXRhID0gKDI6ZGltKGlucHV0X2RhdGEpWzFdKSwgbmZjc3QgPSAyNTAsIG1vZGVsID0xLCBsZXZlbCA9IDAuMDEsIEcgPSA1LCBjb2wgPSAyKXsKICAjIFJ1biB0aGUgdmFycHJlZGljdCBmdW5jdGlvbgogIHZhcnByZWRpY3QgPC0gcm9sbGFwcGx5cihpbnB1dF9kYXRhW3JhbmdlX2RhdGEsY29sXSwgbGVuZ3RoKHJhbmdlX2RhdGEpIC0gbmZjc3QsIGNhdmlhck9wdGltLCBtb2RlbCwgbGV2ZWwsIHByZWRpY3QgPSAxLCBrID0gRykgJT4lIGxhZwogICMgRWxpbWluYXRlIE5BcwogICMgcHJlZF9ub19uYSA9IG5hLm9taXQodmFycHJlZGljdCkKICAjIFJldHVybiB0aGUgZGF0YQogICMgcmV0dXJuKHByZWRfbm9fbmEpCiAgcmV0dXJuKHZhcnByZWRpY3QpCn0KCmBgYAoKYGBge3J9CiMnIEZ1bmN0aW9uIHRvIENhbGN1bGF0ZSBMb3NzIGZyb20gdGhlIGFib3ZlIHByZWRpY3Rpb25zCiMnCiMnIEBwYXJhbSBzeW1ib2wgLSBzeW1ib2wgdG8gd29yayB3aXRoIGZyb20gcXVhbnRtb2QuIE11c3QgYmUgaW4gcXVvdGF0aW9ucyB0byB3b3JrCiMnIEBwYXJhbSBzdGFydF9kdCAtIHN0YXJ0IGRhdGUgb2YgdGhlIGRhdGEgdG8gYnVpbGQgdGhlIGZvcmVjYXN0IG9uIAojJyBAcGFyYW0gZW5kX2R0IC0gZW5kIGRhdGUgb2YgdGhlIGRhdGEgdG8gYnVpbGQgdGhlIGZvcmVjYXN0IG9uICAKIycgQHBhcmFtIG5mY3N0IC0gbnVtYmVyIG9mIGRhdGEgcG9pbnRzIHRvIHVzZSBpbiB0aGUgZm9yZWNhc3QKIycgQHBhcmFtIG1vZGVsIC0gbW9kZWwgdG8gdXNlLiBEZWZhdWx0cyB0byAxCiMnIEBwYXJhbSBsZXZlbCAtIGxldmVsIG9mIHNpZ25pZmljYW5jZS4gRGVmYXVsdHMgdG8gMSUKIycgQHBhcmFtIEcgLSBhcmd1bWVudCBmb3IgdGhlIGsgcGFyYW1ldGVyIGluIHRoZSA0dGggbW9kZWwgKGFkYXB0aXZlKS4gRGVmYXVsdCBpcyA1CiMnCiMnIEByZXR1cm4gLSBsb3NzIHVzaW5nIGFic29sdXRlIHZhbHVlCiMnIEBleHBvcnQgLSBhIHBsb3Qgb2YgdGhlIGRhdGEKIycKIycgQGV4YW1wbGVzCmxvc3NfY2FsY191diA9IGZ1bmN0aW9uKHN5bWJvbCwgc3RhcnRfZHQsIGVuZF9kdCwgbmZjc3QsIG1vZGVsID0gMSwgbGV2ZWwgPSAwLjAxLCBHID0gNSl7CiAgIyBQdWxsIGluIHRoZSBkYXRhCiAgcmF3X2RhdGEgPSBkYXRhX3B1bGwoc3ltYm9sLCBzdGFydF9kYXRlID0gc3RhcnRfZHQsIGVuZF9kYXRlID0gZW5kX2R0KQogICMgRm9yZWNhc3QgYmFzZWQgb24gdGhlIGRhdGEKICBmY3N0ID0gbmEub21pdChyb2xsaW5nX3ByZWRpY3Rpb25zKHJhd19kYXRhLCBuZmNzdCA9IG5mY3N0LCBtb2RlbCA9IG1vZGVsLCBsZXZlbCA9IGxldmVsLCBHID0gRykpKigtMSkKICAjIEV4dHJhY3QgYWN0dWFscwogIGFjdCA9IHRhaWwocmF3X2RhdGEsIG4gPSBuZmNzdClbLDJdCiAgIyBKb2luIHRoZSB0d28gdG9nZXRoZXIgYW5kIHJlbmFtZQogIGpvaW4gPSBtZXJnZShmY3N0LGFjdCxhbGw9VFJVRSkKICBjb2xuYW1lcyhqb2luKSA8LSBjKCJGY3N0X1ZhUiIsICJBY3RfUmV0dXJuIikKICAjIHByaW50KGpvaW4pCiAgIyBDYWxjdWxhdGUgdGhlIGxvc3NlcwogIGxvc3MgPSBhYnMoc3VtKGlmZWxzZShhY3QgPiBmY3N0LCBsZXZlbCwgKC0xKSooMS1sZXZlbCkpKSkKICAjIFBsb3QgdGhlIGRhdGEKICBwbG90ID0gcGxvdC54dHMoam9pbiwgY29sID0gYygicmVkIiwgImJsYWNrIiksIGx0eSA9IGMoMiwxKSwgbWFpbiA9ICJMb2cgUmV0dXJuIGZyb20gdGhlIFNQWSB2cy4gRmNzdC4gVmFSIixncmlkLmNvbCA9IE5BLCBsZWdlbmQubG9jID0gImJvdHRvbWxlZnQiKQogIHJldHVybihsaXN0KGxvc3MsIHBsb3QsIGFjdCwgZmNzdCkpCn0KCmBgYAoKCmBgYHtyLCBjYWNoZSA9IFRSVUV9CiMnIFRoaXMgaXMgYSBmdW5jdGlvbiB3aGljaCBjcmVhdGVzIGEgZGF0YSBmcmFtZSBmb3IgdGhlIHJlc3BvbnNlIGFuZCBleHBsYW5hdG9yeSB2YXJpYWJsZXMgdGhhdCB3ZSdsbCBmZWVkIGludG8gdGhlIGRpZmZ1c2lvbiBpbmRleAojJwojJyBAcGFyYW0gc3ltYm9sX2xpc3QgLSBhIGxpc3Qgb2Ygc3ltYm9scyByZWNvZ25pemFibGUgYnkgdGhlIGdldFN5bWJvbHMgZnVuY3Rpb24KIycgQHBhcmFtIHJlc3BfdmFyIC0gdGhlIHJlc3BvbnNlIHZhcmlhYmxlIHdlJ2QgbGlrZSB0byBmb3JlY2FzdDsgZGVmYXVsdCBpcyBTUFkKIycgQHBhcmFtIGNvbXBsX2Nhc2UgLSBkZWZhdWx0cyB0byB0cnVlLi4ub25seSBpbmNsdWRlcyBjb21wbGV0ZSBjYXNlcyBpbiB0aGUgZGF0YQojJyBAcGFyYW0gYWRqX2Nsb3NlIC0gdXNlIGFkanVzdGVkIGNsb3NpbmcgcHJpY2VzIGZvciB0aGUgZXhwbGFuYXRvcnkgdmFyaWFibGVzPyBkZWZhdWx0IGlzIDEgZm9yIFlFUwojJyBAcGFyYW0gcmVzcF9hZGpfY2xvc2UgLSB1c2UgYWRqdXN0ZWQgY2xvc2luZyBwcmljZXMgZm9yIHRoZSBleHBsYW5hdG9yeSB2YXJpYWJsZXM/IGRlZmF1bHQgaXMgMSBmb3IgWUVTCiMnIEBwYXJhbSBzdGFydF9kYXRlIC0gc3RhcnRpbmcgZGF0YSB0byB1c2UKIycgQHBhcmFtIGVuZF9kYXRlIC0gZW5kaW5nIGRhdGUgb2YgdGhlIGRhdGEKIycgQHBhcmFtIGxhZ19wcmVkIC0gZG8gd2UgbGFnIHRoZSBwcmVkaWN0aW9ucz8gSXQgaXMgU1RST05HTFkgcmVjb21tZW5kZWQgdGhhdCB0aGlzIGlzIDAKIycKIycgQHJldHVybiAtIGEgZGF0YSBmcmFtZSB3aGljaCBjYW4gYmUgZmVkIGludG8gdGhlIFNXZm9yZSBmdW5jdGlvbgojJyBAZXhwb3J0CiMnCiMnIEBleGFtcGxlcyAtIGRpZmZfaW5kZXhfZGYoYygiWExGIiwgIlhMRSIsICJQU0NUIiwgIlhMViIsICJWUFUiLCAiWExQIiwgIklHRiIsICJYV0VCIiwgIlBQVFkiKSkKZGlmZl9pbmRleF9kZiA9IGZ1bmN0aW9uKHN5bWJvbF9saXN0LCByZXNwX3ZhciA9ICJTUFkiLCBjb21wbF9jYXNlID0gMSwgYWRqX2Nsb3NlID0gMSwgcmVzcF9hZGpfY2xvc2UgPSAxLCBzdGFydF9kYXRlID0gIjE5MDAtMDEtMDEiLCBlbmRfZGF0ZSA9IFN5cy5EYXRlKCksIGxhZ19wcmVkID0gMSl7CiAgIyBQdWxsIGluIHJlc3BvbnNlIHZhcmlhYmxlCiAgcmVzcG9uc2VfcHVsbCA9IGdldFN5bWJvbHMocmVzcF92YXIsIGF1dG8uYXNzaWduID0gRkFMU0UsIGZyb20gPSBzdGFydF9kYXRlLCB0byA9IGVuZF9kYXRlKQogICMgR2V0IGFkanVzdGVkIGNsb3NpbmcgcHJpY2UKICBpZiAocmVzcF9hZGpfY2xvc2UgPT0gVFJVRSl7CiAgICBkaWZmX2RmID0gQWQocmVzcG9uc2VfcHVsbCkKICB9IGVsc2UgewogICAgZGlmZl9kZiA9IENsKHJlc3BvbnNlX3B1bGwpCiAgfQogICMgTG9vcCB0aHJvdWdoIHRoZSBzeW1ib2xzIGFuZCBqb2luIGluIGRhdGEKICBmb3IgKGkgaW4gMTpsZW5ndGgoc3ltYm9sX2xpc3QpKXsKICAgICMgUHVsbCBjbG9zaW5nIHByaWNlCiAgICBleHBsX3B1bGwgPSBnZXRTeW1ib2xzKHN5bWJvbF9saXN0W2ldLCBhdXRvLmFzc2lnbiA9IEZBTFNFLCBmcm9tID0gc3RhcnRfZGF0ZSwgdG8gPSBlbmRfZGF0ZSkKICAgICMgRXh0cmFjdCBjbG9zaW5nIHByaWNlIC0gNHRoIGVsZW1lbnQKICAgIGlmIChhZGpfY2xvc2UgPT0gVFJVRSl7CiAgICAgIGV4cGxfY2wgPSBBZChleHBsX3B1bGwpCiAgICB9IGVsc2UgewogICAgICBleHBsX2NsID0gQ2woZXhwbF9wdWxsKQogICAgfQogICAgIyBOZXcgY29kZSBmb3IgNC4xNi4yMDIwIC0gbGFnIHRoZSBleHBsYW5hdG9yeSB2YXJpYWJsZXMKICAgIGlmIChsYWdfcHJlZCA9PSBUUlVFKXsKICAgICAgIyBMYWcgdGhlIGV4cGxhbmF0b3J5IHZhcmlhYmxlcyBieSAxCiAgICAgIGxhZ19leHAgPSBzdGF0czo6bGFnKGV4cGxfY2wsIDEpCiAgICAgICMgQXBwZW5kIHRoZSBmaXJzdCBsYWcgdG8gdGhlIGRhdGEgZnJhbWUKICAgICAgZGlmZl9kZiA9IG1lcmdlKGRpZmZfZGYsIGxhZ19leHAsIGpvaW4gPSAibGVmdCIsIGZpbGwgPSBOQSkKICAgIH0gZWxzZXsKICAgICAgIyBSZXR1cm4gdGhlIGRhdGEgZnJhbWUgd2l0aG91dCBsYWdzCiAgICAgIGRpZmZfZGYgPSBtZXJnZShkaWZmX2RmLCBleHBsX2NsLCBqb2luID0gImxlZnQiLCBmaWxsID0gTkEpCiAgICB9CiAgfQogIGlmIChsYWdfcHJlZCA9PSBUUlVFKXsKICAgICMgQ2hvcCBvZmYgdGhlIGZpcnN0IHJvdwogICAgZGlmZl9kZiA9IGRpZmZfZGZbLTEsXQogIH0KICBlbHNlIHsKICAgIHByaW50KCJQTEVBU0UgTk9URSAtIHRoZSBleHBsYW5hdG9yeSB2YXJpYWJsZXMgaW4gdGhpcyBERiBhcmUgTk9UIGxhZ2dlZC4gQmUgY2FyZWZ1bCB0byBhdm9pZCBsb29rLWFoZWFkIGJpYXMhIikKICB9CiAgIyBSZXR1cm4gY29tcGxldGUgY2FzZXMgb25seSAKICBpZiAoY29tcGxfY2FzZSA9PSBUUlVFKXsKICAgIGRpZmZfZGZfb3V0ID0gZGlmZl9kZltjb21wbGV0ZS5jYXNlcyhkaWZmX2RmKSwgXQogIH0gZWxzZXsKICAgIGRpZmZfZGZfb3V0ID0gZGlmZl9kZgogIH0KICAKICByZXR1cm4oZGlmZl9kZl9vdXQpCn0KCmBgYAoKYGBge3IsIGNhY2hlID0gVFJVRX0KIycgQ29udmVydHMgYSBkaWZmX2RmIGludG8gYSBkYXRhIGZyYW1lIHdpdGggYXBwcm94aW1hdGUgcGVyY2VudGFnZSBjaGFuZ2VzIGRpZmYobG9nKGRpZmZfZGYpKQojJwojJyBAcGFyYW0gZGlmZl9kZiAtIG91dHB1dCBvZiB0aGUgZGlmZl9pbmRleF9kZiBmdW5jdGlvbiB3aXRoIGNvbXBsZXRlIGNhc2VzCiMnCiMnIEByZXR1cm4gLSByZXR1bnMgdGhlIGRpZmZlcmVuY2VkIGRhdGEKIycgQGV4cG9ydAojJwojJyBAZXhhbXBsZXMgLSBwY19kaWZmX2luZGV4KHRlc3RfY29tcGwpIAoKcGNfZGlmZl9pbmRleCA9IGZ1bmN0aW9uKGRpZmZfZGYpewogICMgRGlmZmVyZW5jZSB0aGUgbG9nIG9mIHRoZSBkYXRhCiAgcGNfZGlmZl9pbmRleCA9IGRpZmYobG9nKGRpZmZfZGYpKQogICMgUmVtb3ZlIHRoZSBmaXJzdCByb3cKICBwY19kaWZmX2luZGV4X291dCA9IHBjX2RpZmZfaW5kZXhbLTEsXQogIHJldHVybihwY19kaWZmX2luZGV4X291dCkKfQoKYGBgCgoKYGBge3J9CiMnIEJlbG93IGlzIHRoZSBtb2RpZmllZCBkaWZmdXNpb24gaW5kZXggY29kZS4KIycKIycgQHBhcmFtIHkgLSByZXNwb25zZSB2YXJpYWJsZQojJyBAcGFyYW0geCAtIHByZWRpY3RvciB2YXJpYWJsZXMKIycgQHBhcmFtIG9yaWcgLSBmb3JlY2FzdCBvcmlnaW4KIycgQHBhcmFtIG0gLSBudW1iZXIgb2YgZGlmZnVzaW9uIGluZGV4ZXMgdXNlZAojJyBAcGFyYW0gdGF1IC0gVmFSIGxldmVsIHRvIHVzZTsgbXVzdCBiZSBiZXR3ZWVuIDAgYW5kIDEKIycgQHBhcmFtIGVuZCAtIHNwZWNpZmllcyBhbiBhbHRlcm5hdGUgZW5kaW5nIHZhbHVlCiMnIEBwYXJhbSBwcmludF9tZGwgLSBwcmludCB0aGUgbW9kZWwgc3VtbWFyeSBhbmQgdGhlIE1TRQojJwojJyBAcmV0dXJuIC0gcmV0dXJucyBhIGxpc3Qgb2YgdmFyaWFibGVzIGZvciB1c2UgaW4gdGhlIGRpZmZ1c2lvbiBpbmRleAojJyBAZXhwb3J0CiMnCiMnIEBleGFtcGxlcwptb2RfZGkgPSBmdW5jdGlvbiAoeSwgeCwgb3JpZywgbSwgdGF1LCBlbmQgPSBOVUxMLCBwcmludF9tZGwgPSAwKSAKewogICMgQ29udmVydHMgdGhlIHJlc3BvbnNlIHZhcmlhYmxlcyBpbnRvIGEgbWF0cml4CiAgaWYgKCFpcy5tYXRyaXgoeCkpIAogICAgICB4ID0gYXMubWF0cml4KHgpCiAgIyBuVCBpcyBudW1iZXIgb2YgdCB0aW1lLXN0ZXBzCiAgblQgPSBkaW0oeClbMV0KICAjIEFkZCBhIGxpbmUgdG8gZXN0YWJsaXNoIHRoZSBudW1iZXIgb2YgZGF0YSBwb2ludHMgdXNlZCBpbiB0aGUgdGVzdC4KICBpZiAoaXMubnVsbChlbmQpICE9IFRSVUUpewogICAgblQgPSBlbmQKICB9CiAgIyBrIGlzIHRoZSBudW1iZXIgb2YgZGlmZnVzaW9uIGluZGljZXMgdXNlZAogIGsgPSBkaW0oeClbMl0KICAjIFNhbml0eSBjaGVja3MgdG8gZW5zdXJlIHRoYXQgdGhlIG9yaWdpbiBpc24ndCBwYXN0IHRoZSBudW1iZXIgb2YgdGltZSBwb2ludHMKICBpZiAob3JpZyA+IG5UKSAKICAgICAgb3JpZyA9IG5UCiAgIyBNYWtlcyBzdXJlIHRoYXQgdGhlcmUgYXJlbid0IG1vcmUgcHJlZGljdG9ycyB0aGFuIHRoZXJlIHZhcmlhYmxlcyBpbiB0aGUgZGF0YXNldAogIGlmIChtID4gaykgCiAgICAgIG0gPSBrCiAgIyBNYWtlcyBzdXJlIHRoZXJlIGFyZSBhdCBsZWFzdCBzb21lIHZhcmlhYmxlcwogIGlmIChtIDwgMSkgCiAgICAgIG0gPSAxCiAgIyBTdWJkaXZpZGVzIHRoZSBkYXRhZnJhbWUKICB4MSA9IHhbMTpvcmlnLCBdCiAgIyBDYWxjdWxhdGVzIG1lYW5zIG9mIGVhY2ggcm93CiAgbWUgPSBhcHBseSh4MSwgMiwgbWVhbikKICAjIENhbGN1bGF0ZXMgc3RhbmRhcmQgZGV2aWF0aW9ucyBvZiBlYWNoIGNvbHVtbgogIHNlID0gc3FydChhcHBseSh4MSwgMiwgdmFyKSkKICAjIENyZWF0ZXMgYSBtYXRyaXggeDEsIHdoaWNoIG5vcm1hbGl6ZXMgYWxsIHRoZSBjb2x1bW5zLiAKICAjIFRoaXMgbWF5IGJlIGFuIGlzc3VlIHNpbmNlIGl0IGFzc3VtZXMgdGhhdCB0aGUgZGlzdHJpYnV0aW9uIGlzIHN1ZmZpY2llbnRseSBkZXNjcmliZWQgYnkgdGhlIGZpcnN0IHR3byBtb21lbnRzCiAgeDEgPSB4CiAgZm9yIChpIGluIDE6aykgewogICAgICB4MVssIGldID0gKHgxWywgaV0gLSBtZVtpXSkvc2VbaV0KICB9CiAgVjEgPSBjb3YoeDFbMTpvcmlnLCBdKQogICMgUGVyZm9ybXMgYW4gZWlnZW4gZGVjb21wb3NpdGlvbgogIG0xID0gZWlnZW4oVjEpCiAgIyBTZWxlY3RzIGVpZ2VudmFsdWVzCiAgc2RldiA9IG0xJHZhbHVlcwogICMgU2VsZWN0cyBlaWdlbnZlY3RvcnMKICBNID0gbTEkdmVjdG9ycwogICMgTWFrZXMgYSBzbWFsbGVyIG1hdHJpeAogIE0xID0gTVssIDE6bV0KICAjIFRoaXMgaXMgdGhlIGRpZmZ1c2lvbiBpbmRleCBtb2RlbCAtIFtvcmlnIHggcF0qW3AgeCBtXSA9IFtvcmlnIHggbV0KICBEaW5kZXggPSB4MSAlKiUgTTEKICAjIEN1dCBkb3duIGJvdGggdGhlIHJlc3BvbnNlIGFuZCBwcmVkaWN0b3JzIHRvIGJlIGEgcmVhc29uYWJsZSBzaXplCiAgeTEgPSB5WzE6b3JpZ10KICBERiA9IERpbmRleFsxOm9yaWcsIF0KICAjIEFwcGx5IHRoZSBsaW5lYXIgbW9kZWwgLSBIRVJFIGlzIHRoZSBrZXkuCiAgIyBtbSA9IGxtKHkxIH4gREYpIC0gb2xkIGZ1bmN0aW9uCiAgbW0gPSBycSh5MSB+IERGLCB0YXUgPSB0YXUpCiAgIyBQcmludCB0aGUgZGF0YQogIGlmIChwcmludF9tZGwgPT0gMSl7CiAgICBwcmludChzdW1tYXJ5KG1tKSkKICB9CiAgIyBQdXRzIGNvZWZmaWNpZW50cyBpbiBhIG1hdHJpeAogIGNvZWYgPSBtYXRyaXgobW0kY29lZmZpY2llbnRzLCAobSArIDEpLCAxKQogICMgSW5pdGlhbGl6ZXMgeWhhdCB2YXJpYWJsZXMgYW5kIE1TRQogIHloYXQgPSBOVUxMCiAgTVNFID0gTlVMTAogIGlmIChvcmlnIDwgblQpIHsKICAgICMgQ3JlYXRlcyBhIG5mY3N0IGJ5IChtKzEpIG1hdHJpeAogICAgbmV3eCA9IGNiaW5kKHJlcCgxLCAoblQgLSBvcmlnKSksIERpbmRleFsob3JpZyArIDEpOm5ULCAKICAgICAgICBdKQogICAgIyBbbmZjc3R4KG0rMSldKlsobSsxKXgxXSA9IFtuZmNzdHgxXQogICAgeWhhdCA9IG5ld3ggJSolIGNvZWYKICAgICMgQ2FsY3VsYXRlcyBlcnJvcnMKICAgIGVyciA9IHlbKG9yaWcgKyAxKTpuVF0gLSB5aGF0CiAgICBNU0UgPSBtZWFuKGVycl4yKQogICAgaWYgKHByaW50X21kbCA9PSAxKXsKICAgICAgY2F0KCJNU0Ugb2Ygb3V0LW9mLXNhbXBsZSBmb3JlY2FzdHM6ICIsIE1TRSwgIlxuIikKICAgIH0KICB9CiAgU1dmb3JlIDwtIGxpc3QoY29lZiA9IGNvZWYsIHloYXQgPSB5aGF0LCBNU0UgPSBNU0UsIGxvYWRpbmdzID0gTTEsIAogICAgICBERmluZGV4ID0gRGluZGV4KQp9CgpgYGAKCgpgYGB7cn0KIycgQmVsb3cgaXMgdGhlIG1vZGlmaWVkIGRpZmZ1c2lvbiBpbmRleCBjb2RlIHRvIGluY2x1ZGUgbGFnZ2VkIHZhcmlhYmxlcy4KIycKIycgQHBhcmFtIHkgLSByZXNwb25zZSB2YXJpYWJsZQojJyBAcGFyYW0geCAtIHByZWRpY3RvciB2YXJpYWJsZXMKIycgQHBhcmFtIG9yaWcgLSBmb3JlY2FzdCBvcmlnaW4KIycgQHBhcmFtIG0gLSBudW1iZXIgb2YgZGlmZnVzaW9uIGluZGV4ZXMgdXNlZAojJyBAcGFyYW0gdGF1IC0gVmFSIGxldmVsIHRvIHVzZTsgbXVzdCBiZSBiZXR3ZWVuIDAgYW5kIDEKIycgQHBhcmFtIGFyX3RmIC0gQVIgdHJhbnNmb3JtYXRpb24gdHlwZS4gKDEgLSBubyB0cmFuc2Zvcm1hdGlvbiwKIycgMiAtIGFic29sdXRlIHZhbHVlLCAzIC0gYXN5bW1ldHJpYyBzbG9wZSkKIycgQHBhcmFtIHAgLSBudW1iZXIgb2YgQVIgbGFncyB0byBpbmNsdWRlLiBEZWZhdWx0IGlzIG9uZS4KIycgQHBhcmFtIHByaW50X21kbCAtIG9wdGlvbiB0byBwcmludCB0aGUgbW9kZWwgc3VtbWFyeSB0byBtYWtlIHN1cmUgZXZlcnl0bmluZyBpcyBvay4gMCBpcyBkZWZhdWx0LgojJyBAcGFyYW0gbW9kZWwgLSBtb2RlbCB0eXBlICgxIC0gU0FWLCAyIC0gQVMsIDMgLSBHQVJDSCwgNCAtIEFEQVBUSVZFKSAKIycKIycgQHJldHVybiAtIHJldHVybnMgYSBsaXN0IG9mIHZhcmlhYmxlcyBmb3IgdXNlIGluIHRoZSBkaWZmdXNpb24gaW5kZXgKIycgQGV4cG9ydAojJwojJyBAZXhhbXBsZXMKbW9kX2RpX3dsID0gZnVuY3Rpb24gKHksIHgsIG9yaWcsIG0sIHRhdSwgYXJfdGYgPSAxLCBwID0gMSwgcHJpbnRfbWRsID0gMCwgbW9kZWwgPSAxLCBlbmQgPSBOVUxMKSAKewogICMgQ29udmVydHMgdGhlIHJlc3BvbnNlIHZhcmlhYmxlcyBpbnRvIGEgbWF0cml4CiAgaWYgKCFpcy5tYXRyaXgoeCkpIAogICAgICB4ID0gYXMubWF0cml4KHgpCiAgIyBuVCBpcyBudW1iZXIgb2YgdCB0aW1lLXN0ZXBzCiAgblQgPSBkaW0oeClbMV0KICAjIEFkZCBhIGxpbmUgdG8gZXN0YWJsaXNoIHRoZSBudW1iZXIgb2YgZGF0YSBwb2ludHMgdXNlZCBpbiB0aGUgdGVzdC4KICBpZiAoaXMubnVsbChlbmQpICE9IFRSVUUpewogICAgblQgPSBlbmQKICB9CiAgIyBrIGlzIHRoZSBudW1iZXIgb2YgZGlmZnVzaW9uIGluZGljZXMgdXNlZAogIGsgPSBkaW0oeClbMl0KICAjIFNhbml0eSBjaGVja3MgdG8gZW5zdXJlIHRoYXQgdGhlIG9yaWdpbiBpc24ndCBwYXN0IHRoZSBudW1iZXIgb2YgdGltZSBwb2ludHMKICBpZiAob3JpZyA+IG5UKSAKICAgICAgb3JpZyA9IG5UCiAgIyBNYWtlcyBzdXJlIHRoYXQgdGhlcmUgYXJlbid0IG1vcmUgcHJlZGljdG9ycyB0aGFuIHRoZXJlIHZhcmlhYmxlcyBpbiB0aGUgZGF0YXNldAogIGlmIChtID4gaykgCiAgICAgIG0gPSBrCiAgIyBNYWtlcyBzdXJlIHRoZXJlIGFyZSBhdCBsZWFzdCBzb21lIHZhcmlhYmxlcwogIGlmIChtIDwgMSkgCiAgICAgIG0gPSAxCiAgIyBTdWJkaXZpZGVzIHRoZSBkYXRhZnJhbWUKICB4MSA9IHhbMTpvcmlnLCBdCiAgIyBDYWxjdWxhdGVzIG1lYW5zIG9mIGVhY2ggcm93CiAgbWUgPSBhcHBseSh4MSwgMiwgbWVhbikKICAjIENhbGN1bGF0ZXMgc3RhbmRhcmQgZGV2aWF0aW9ucyBvZiBlYWNoIGNvbHVtbgogIHNlID0gc3FydChhcHBseSh4MSwgMiwgdmFyKSkKICAjIENyZWF0ZXMgYSBtYXRyaXggeDEsIHdoaWNoIG5vcm1hbGl6ZXMgYWxsIHRoZSBjb2x1bW5zLiAKICAjIFRoaXMgbWF5IGJlIGFuIGlzc3VlIHNpbmNlIGl0IGFzc3VtZXMgdGhhdCB0aGUgZGlzdHJpYnV0aW9uIGlzIHN1ZmZpY2llbnRseSBkZXNjcmliZWQgYnkgdGhlIGZpcnN0IHR3byBtb21lbnRzCiAgeDEgPSB4CiAgZm9yIChpIGluIDE6aykgewogICAgICB4MVssIGldID0gKHgxWywgaV0gLSBtZVtpXSkvc2VbaV0KICB9CiAgVjEgPSBjb3YoeDFbMTpvcmlnLCBdKQogICMgUGVyZm9ybXMgYW4gZWlnZW4gZGVjb21wb3NpdGlvbgogIG0xID0gZWlnZW4oVjEpCiAgIyBTZWxlY3RzIGVpZ2VudmFsdWVzCiAgc2RldiA9IG0xJHZhbHVlcwogICMgU2VsZWN0cyBlaWdlbnZlY3RvcnMKICBNID0gbTEkdmVjdG9ycwogICMgTWFrZXMgYSBzbWFsbGVyIG1hdHJpeAogIE0xID0gTVssIDE6bV0KICAjIFRoaXMgaXMgdGhlIGRpZmZ1c2lvbiBpbmRleCBtb2RlbCAtIFtvcmlnIHggcF0qW3AgeCBtXSA9IFtvcmlnIHggbV0KICBEaW5kZXggPSB4MSAlKiUgTTEKICAjIEN1dCBkb3duIGJvdGggdGhlIHJlc3BvbnNlIGFuZCBwcmVkaWN0b3JzIHRvIGJlIGEgcmVhc29uYWJsZSBzaXplCiAgeTEgPSB5WzE6b3JpZ10KICBERiA9IERpbmRleFsxOm9yaWcsIF0KICAjIENvcHkgdGhlIGRhdGEgZnJhbWUKICBERl93bCA9IERpbmRleAogICMgTGFnIHRoZSB5LXZhcmlhYmxlCiAgZm9yIChpIGluIDE6cCl7CiAgICAjIENyZWF0ZSBhIGxhZ2dlZCB2YXJpYWJsZQogICAgbGFnX3ZhciA9IGxhZyh5LCBpKQogICAgIyBBcHBlbmQgdGhlIGZpcnN0IGxhZyB0byB0aGUgZGF0YSBmcmFtZQogICAgREZfd2wgPSBjYmluZChERl93bCxsYWdfdmFyKQogIH0KICAjIElkZW50aWZ5IHRoZSByaWdodCBjb2x1bW5zCiAgbF9hciA9IG5jb2woREZfd2wpCiAgZl9hciA9IGxfYXIgLSBwICsgMQogICMgS2VlcCB0aGUgbGFzdCBjb2x1bW5zIGtlcHQgdG8gdGhlIHNpZGUKICBhbGxfbGFnID0gREZfd2xbLChmX2FyOmxfYXIpXQogICMgQ3V0IG9mZiB0aGUgZmlyc3Qgcm93IHRvIGF2b2lkIE5BJ3MKICBERl90cmltID0gREZfd2xbMTpvcmlnLF0KICAjIFJlbmFtZSB0aGUgY29sdW1ucwogICMgSGVyZSdzIHRoZSBuZXcgZnVuY3Rpb24gd2l0aCBhbiB1bnRyYW5zZm9ybWVkIEFSKHApIGxhZwogIGlmIChhcl90ZiA9PSAxKXsKICAgICMgSW5jb3Jwb3JhdGUgZXZlcnl0aGluZyBpbiB0byBhbiBpbnB1dCBkYXRhIGZyYW1lCiAgICBkZl9pbiA9IGNiaW5kKHkxWy0oMTpwKV0sIERGX3RyaW1bLSgxOnApLF0pCiAgICAjIFJlbmFtZSB0aGUgY29sdW1ucwogICAgIyBJbml0aWFsaXplIGEgY2hhcmFjdGVyIHZlY3RvcgogICAgbnZlYyA9IGMocmVwKDAsIDErbStwKSkKICAgICMgUG9wdWxhdGUgdGhlIHZlY3RvciAtIGZpcnN0IHZhbHVlIGlzIHRoZSByZXNwb25zZQogICAgbnZlY1sxXSA8LSBuYW1lcyh5KQogICAgIyBOZXh0IGFyZSB0aGUgZGlmZnVzaW9uIGluZGljZXMKICAgIGZvciAoaSBpbiAxOm0pewogICAgICBudmVjW2krMV0gPSBwYXN0ZTAoIkRpZmZfSW5kZXhfIiwgaSkKICAgIH0KICAgICMgTmV4dCBhcmUgdGhlIGxhZ2dlZCB2YXJpYWJsZXMKICAgIGZvciAoaSBpbiAxOnApewogICAgICBudmVjW2krMSttXSA9IHBhc3RlMCgiTGFnXyIsIGkpCiAgICB9CiAgICAjIEFzc2lnbiB0aGUgbmFtZXMKICAgIG5hbWVzKGRmX2luKSA8LSBudmVjCiAgICAjIFJ1biB0aGUgbW9kZWwKICAgIG1tID0gcnEoZGZfaW5bLDFdIH4gZGZfaW5bLC0xXSwgdGF1ID0gdGF1KQogIH0KICAjIEhlcmUncyB0aGUgbmV3IGZ1bmN0aW9uIHdpdGggYW4gU0FWIEFSKHApIGxhZwogIGlmIChhcl90ZiA9PSAyKXsKICAgICMgSW5jb3Jwb3JhdGUgZXZlcnl0aGluZyBpbiB0byBhbiBpbnB1dCBkYXRhIGZyYW1lCiAgICBkZl9pbiA9IGNiaW5kKHkxWy0oMTpwKV0sIERGX3RyaW1bLSgxOnApLC0oZl9hcjpsX2FyKV0sIGFicyhERl90cmltWy0oMTpwKSwoZl9hcjpsX2FyKV0pKQogICAgIyBSZW5hbWUgdGhlIGNvbHVtbnMKICAgICMgSW5pdGlhbGl6ZSBhIGNoYXJhY3RlciB2ZWN0b3IKICAgIG52ZWMgPSBjKHJlcCgwLCAxK20rcCkpCiAgICAjIFBvcHVsYXRlIHRoZSB2ZWN0b3IgLSBmaXJzdCB2YWx1ZSBpcyB0aGUgcmVzcG9uc2UKICAgIG52ZWNbMV0gPC0gbmFtZXMoeSkKICAgICMgTmV4dCBhcmUgdGhlIGRpZmZ1c2lvbiBpbmRpY2VzCiAgICBmb3IgKGkgaW4gMTptKXsKICAgICAgbnZlY1tpKzFdID0gcGFzdGUwKCJEaWZmX0luZGV4XyIsIGkpCiAgICB9CiAgICAjIE5leHQgYXJlIHRoZSBsYWdnZWQgdmFyaWFibGVzCiAgICBmb3IgKGkgaW4gMTpwKXsKICAgICAgbnZlY1tpKzErbV0gPSBwYXN0ZTAoIkxhZ18iLCBpKQogICAgfQogICAgIyBBc3NpZ24gdGhlIG5hbWVzLiBOb3RlIHRoYXQgdGhpcyBpcyBhIG1hdHJpeAogICAgbmFtZXMoZGZfaW4pIDwtIG52ZWMKICAgICMgUnVuIHRoZSBtb2RlbAogICAgbW0gPSBycShkZl9pblssMV0gfiBkZl9pblssLTFdLCB0YXUgPSB0YXUpCiAgfQogICMgSGVyZSdzIHRoZSBuZXcgZnVuY3Rpb24gd2l0aCBhbiBhc3ltbWV0cmljIHNsb3BlIGZvciB0aGUgQVIoMSkgbGFnCiAgIyBJbmRpY2F0b3I7IDAgaWYgcGVyY2VudCBjaGFuZ2UgaXMgbmVnYXRpdmUsIDEgaWYgaXQncyBwb3NpdGl2ZQogICMgaW5kaSA9IGlmZWxzZShERl90cmltWyxhcl0gPCAwLCAwLCAxKQogIGlmIChhcl90ZiA9PSAzKXsKICAgICMgQ3JlYXRlIGEgbWF0cml4IG9mIGluZGljYXRvcnMKICAgIGluZGlfbWF0ID0gbWF0cml4KDAsIG5yb3coREZfd2wpLCBwKQogICAgIyBHZW5lcmFsaXplIHRoZSBhYm92ZSBjb2RlCiAgICBmb3IgKGkgaW4gMTpwKXsKICAgICAgIyBQb3B1bGF0ZSB0aGUgaW5kaWNhdG9yCiAgICAgIGluZGlfbWF0WyxpXSA9IGlmZWxzZShERl93bFssZl9hciArIGkgLSAxXSA8IDAsIDAsIDEpCiAgICB9CiAgfQogICMgRml0dGluZyB0aGUgcmVncmVzc2lvbgogIGlmIChhcl90ZiA9PSAzKXsKICAgICMgSW5jb3Jwb3JhdGUgZXZlcnl0aGluZyBpbiB0byBhbiBpbnB1dCBkYXRhIGZyYW1lCiAgICBkZl9pbiA9IGNiaW5kKHkxWy0oMTpwKV0sIERGX3RyaW1bLSgxOnApLC0oZl9hcjpsX2FyKV0sIERGX3RyaW1bLSgxOnApLChmX2FyOmxfYXIpXSwgaW5kaV9tYXRbKChwKzEpOm9yaWcpLF0pCiAgICAjIFJlbmFtZSB0aGUgY29sdW1ucwogICAgIyBJbml0aWFsaXplIGEgY2hhcmFjdGVyIHZlY3RvcgogICAgbnZlYyA9IGMocmVwKDAsIDErbSsyKnApKQogICAgIyBQb3B1bGF0ZSB0aGUgdmVjdG9yIC0gZmlyc3QgdmFsdWUgaXMgdGhlIHJlc3BvbnNlCiAgICBudmVjWzFdIDwtIG5hbWVzKHkpCiAgICAjIE5leHQgYXJlIHRoZSBkaWZmdXNpb24gaW5kaWNlcwogICAgZm9yIChpIGluIDE6bSl7CiAgICAgIG52ZWNbaSsxXSA9IHBhc3RlMCgiRGlmZl9JbmRleF8iLCBpKQogICAgfQogICAgIyBOZXh0IGFyZSB0aGUgbGFnZ2VkIHZhcmlhYmxlcwogICAgZm9yIChpIGluIDE6cCl7CiAgICAgIG52ZWNbaSsxK21dID0gcGFzdGUwKCJMYWdfIiwgaSkKICAgIH0KICAgICMgTGFzdCBhcmUgdGhlIHBvc2l0aXZlIGluZGljYXRvciB2YXJpYWJsZXMKICAgIGZvciAoaSBpbiAxOnApewogICAgICBudmVjW2krMSttK3BdID0gcGFzdGUwKCJQb3NfVmFsX2Zvcl9MYWdfIiwgaSkKICAgIH0KICAgICMgQXNzaWduIHRoZSBuYW1lcy4gTm90ZSB0aGF0IHRoaXMgaXMgYSBtYXRyaXgKICAgIG5hbWVzKGRmX2luKSA8LSBudmVjCiAgICAjIFJ1biB0aGUgbW9kZWwKICAgIG1tID0gcnEoZGZfaW5bLDFdIH4gZGZfaW5bLC0xXSwgdGF1ID0gdGF1KQogICAgIyBtbSA9IHJxKHkxWy0oMTpwKV0gfiBERl90cmltWy0oMTpwKSwtKGZfYXI6bF9hcildICsgREZfdHJpbVstKDE6cCksKGZfYXI6bF9hcildICsgaW5kaV9tYXRbKChwKzEpOm9yaWcpLF0sIHRhdSA9IHRhdSkKICAgICMgQWRkIGEgZGlmZmVyZW50IGxpbmUgdG8gYWNjb3VudCBmb3IgdGhlIGluZGljYXRvciB2YXJpYWJsZQogICAgIyBpbnRlcmNlcHQgKyBtICsgMipubGFnIHRvIGFjY291bnQgZm9yIHRoZSBudW1iZXIgb2YgaW5kaWNhdG9yIHZhcmlhYmxlcwogICAgY29lZiA9IG1hdHJpeChtbSRjb2VmZmljaWVudHMsICgxICsgbSArIDIqcCksIDEpCiAgfQogIGlmIChwcmludF9tZGwgPT0gMSl7CiAgICBwcmludChzdW1tYXJ5KG1tKSkKICB9CiAgIyBQdXRzIGNvZWZmaWNpZW50cyBpbiBhIG1hdHJpeCAtIGFkZGVkIHRoZSBBUiB0ZXJtcwogICMgY29lZiA9IG1hdHJpeChtbSRjb2VmZmljaWVudHMsIChtICsgMSksIDEpCiAgaWYgKGFyX3RmICE9IDMpewogICAgY29lZiA9IG1hdHJpeChtbSRjb2VmZmljaWVudHMsICgxICsgbSArIHApLCAxKQogIH0KICAjIEluaXRpYWxpemVzIHloYXQgdmFyaWFibGVzIGFuZCBNU0UKICB5aGF0ID0gTlVMTAogIGxvc3MgPSBOVUxMCiAgaWYgKG9yaWcgPCBuVCkgewogICAgIyBDcmVhdGVzIGEgbmZjc3QgYnkgKG0rMikgbWF0cml4CiAgICAjIEFkZCBvbiB0aGUgbGFnZ2VkIHZhcmlhYmxlcwogICAgbmV3eCA9IGNiaW5kKHJlcCgxLCAoblQgLSBvcmlnKSksIERpbmRleFsob3JpZyArIDEpOm5ULCBdLCBhbGxfbGFnWyhvcmlnKzEpOm5ULF0pCiAgICAjIEluY29ycG9yYXRlIGxhZ2dlZCB2YXJpYWJsZXMKICAgIGlmIChhcl90ZiA9PSAzKXsKICAgICAgbmV3eCA9IGNiaW5kKHJlcCgxLCAoblQgLSBvcmlnKSksIERpbmRleFsob3JpZyArIDEpOm5ULCBdLCBhbGxfbGFnWyhvcmlnKzEpOm5ULF0sIGluZGlfbWF0WyhvcmlnKzEpOm5ULF0pCiAgICB9CiAgICAjIFtuZmNzdHgobSsxKV0qWyhtKzEpeDFdID0gW25mY3N0eDFdCiAgICB5aGF0ID0gbmV3eCAlKiUgY29lZgogICAgIyBDYWxjdWxhdGVzIGVycm9ycwogICAgbG9zcyA9IGFicyhzdW0oaWZlbHNlKHlbKG9yaWcgKyAxKTpuVF0gPiB5aGF0LCB0YXUsICgtMSkqKDEtdGF1KSkpKQogICAgIyBNb2RpZnlpbmcgdGhpcyBwYXJ0IHRvIG9ubHkgcHJpbnQgdGhpcyBpZiBzcGVjaWZpZWQKICAgIGlmIChwcmludF9tZGwgPT0gMSl7CiAgICAgIGNhdCgiTG9zc2VzIG9mIG91dC1vZi1zYW1wbGUgZm9yZWNhc3RzOiAiLCBsb3NzLCAiXG4iKQogICAgfQogIH0KICBTV2ZvcmUgPC0gbGlzdChjb2VmID0gY29lZiwgeWhhdCA9IHloYXQsIGxvc3MgPSBsb3NzLCBsb2FkaW5ncyA9IE0xLCAKICAgICAgREZpbmRleCA9IERpbmRleCwgbmFtZV92ZWN0b3IgPSBudmVjKQp9CgpgYGAKCgpgYGB7cn0KCiMnIEJlbG93IGlzIHRoZSBtb2RpZmllZCBkaWZmdXNpb24gaW5kZXggY29kZSB0byBpbmNsdWRlIGxhZ2dlZCB2YXJpYWJsZXMuCiMnCiMnIEBwYXJhbSB5IC0gcmVzcG9uc2UgdmFyaWFibGUKIycgQHBhcmFtIHggLSBwcmVkaWN0b3IgdmFyaWFibGVzCiMnIEBwYXJhbSBvcmlnIC0gZm9yZWNhc3Qgb3JpZ2luCiMnIEBwYXJhbSBtIC0gbnVtYmVyIG9mIGRpZmZ1c2lvbiBpbmRleGVzIHVzZWQKIycgQHBhcmFtIHRhdSAtIFZhUiBsZXZlbCB0byB1c2U7IG11c3QgYmUgYmV0d2VlbiAwIGFuZCAxCiMnIEBwYXJhbSBhcl90ZiAtIEFSIHRyYW5zZm9ybWF0aW9uIHR5cGUuICgxIC0gbm8gdHJhbnNmb3JtYXRpb24sCiMnIDIgLSBhYnNvbHV0ZSB2YWx1ZSwgMyAtIGFzeW1tZXRyaWMgc2xvcGUpCiMnIEBwYXJhbSBwIC0gbnVtYmVyIG9mIEFSIGxhZ3MgdG8gaW5jbHVkZS4gRGVmYXVsdCBpcyBvbmUuCiMnIEBwYXJhbSBwcmludF9tZGwgLSBvcHRpb24gdG8gcHJpbnQgdGhlIG1vZGVsIHN1bW1hcnkgdG8gbWFrZSBzdXJlIGV2ZXJ5dG5pbmcgaXMgb2suIDAgaXMgZGVmYXVsdC4KIycgQHBhcmFtIG1vZGVsIC0gbW9kZWwgdHlwZSAoMSAtIFNBViwgMiAtIEFTLCAzIC0gR0FSQ0gsIDQgLSBBREFQVElWRSkgCiMnCiMnIEByZXR1cm4gLSByZXR1cm5zIGEgbGlzdCBvZiB2YXJpYWJsZXMgZm9yIHVzZSBpbiB0aGUgZGlmZnVzaW9uIGluZGV4CiMnIEBleHBvcnQKIycKIycgQGV4YW1wbGVzCnBjYV9hdF90ID0gZnVuY3Rpb24gKHksIHgsIG9yaWcsIG0sIHRhdSA9IDAuMDEsIGFyX3RmID0gMSwgcCA9IDEsIHByaW50X21kbCA9IDAsIG1vZGVsID0gMSwgZW5kID0gTlVMTCl7CiAgIyBDb252ZXJ0cyB0aGUgcmVzcG9uc2UgdmFyaWFibGVzIGludG8gYSBtYXRyaXgKICBpZiAoIWlzLm1hdHJpeCh4KSkgCiAgICAgIHggPSBhcy5tYXRyaXgoeCkKICAjIG5UIGlzIG51bWJlciBvZiB0IHRpbWUtc3RlcHMKICBuVCA9IGRpbSh4KVsxXQogICMgQWRkIGEgbGluZSB0byBlc3RhYmxpc2ggdGhlIG51bWJlciBvZiBkYXRhIHBvaW50cyB1c2VkIGluIHRoZSB0ZXN0LgogIGlmIChpcy5udWxsKGVuZCkgIT0gVFJVRSl7CiAgICBuVCA9IGVuZAogIH0KICAjIGsgaXMgdGhlIG51bWJlciBvZiBkaWZmdXNpb24gaW5kaWNlcyB1c2VkCiAgayA9IGRpbSh4KVsyXQogICMgU2FuaXR5IGNoZWNrcyB0byBlbnN1cmUgdGhhdCB0aGUgb3JpZ2luIGlzbid0IHBhc3QgdGhlIG51bWJlciBvZiB0aW1lIHBvaW50cwogIGlmIChvcmlnID4gblQpIAogICAgICBvcmlnID0gblQKICAjIE1ha2VzIHN1cmUgdGhhdCB0aGVyZSBhcmVuJ3QgbW9yZSBwcmVkaWN0b3JzIHRoYW4gdGhlcmUgdmFyaWFibGVzIGluIHRoZSBkYXRhc2V0CiAgaWYgKG0gPiBrKSAKICAgICAgbSA9IGsKICAjIE1ha2VzIHN1cmUgdGhlcmUgYXJlIGF0IGxlYXN0IHNvbWUgdmFyaWFibGVzCiAgaWYgKG0gPCAxKSAKICAgICAgbSA9IDEKICAjIFN1YmRpdmlkZXMgdGhlIGRhdGFmcmFtZQogIHgxID0geFsxOm9yaWcsIF0KICAjIENhbGN1bGF0ZXMgbWVhbnMgb2YgZWFjaCByb3cKICBtZSA9IGFwcGx5KHgxLCAyLCBtZWFuKQogICMgQ2FsY3VsYXRlcyBzdGFuZGFyZCBkZXZpYXRpb25zIG9mIGVhY2ggY29sdW1uCiAgc2UgPSBzcXJ0KGFwcGx5KHgxLCAyLCB2YXIpKQogICMgQ3JlYXRlcyBhIG1hdHJpeCB4MSwgd2hpY2ggbm9ybWFsaXplcyBhbGwgdGhlIGNvbHVtbnMuIAogICMgVGhpcyBtYXkgYmUgYW4gaXNzdWUgc2luY2UgaXQgYXNzdW1lcyB0aGF0IHRoZSBkaXN0cmlidXRpb24gaXMgc3VmZmljaWVudGx5IGRlc2NyaWJlZCBieSB0aGUgZmlyc3QgdHdvIG1vbWVudHMKICB4MSA9IHgKICBmb3IgKGkgaW4gMTprKSB7CiAgICAgIHgxWywgaV0gPSAoeDFbLCBpXSAtIG1lW2ldKS9zZVtpXQogIH0KICBWMSA9IGNvdih4MVsxOm9yaWcsIF0pCiAgIyBQZXJmb3JtcyBhbiBlaWdlbiBkZWNvbXBvc2l0aW9uCiAgbTEgPSBlaWdlbihWMSkKICAjIFNlbGVjdHMgZWlnZW52YWx1ZXMKICBzZGV2ID0gbTEkdmFsdWVzCiAgIyBTZWxlY3RzIGVpZ2VudmVjdG9ycwogIE0gPSBtMSR2ZWN0b3JzCiAgIyBNYWtlcyBhIHNtYWxsZXIgbWF0cml4CiAgTTEgPSBNWywgMTptXQogICMgVGhpcyBpcyB0aGUgZGlmZnVzaW9uIGluZGV4IG1vZGVsIC0gW29yaWcgeCBwXSpbcCB4IG1dID0gW29yaWcgeCBtXQogIERpbmRleCA9IHgxICUqJSBNMQogICMgQ3V0IGRvd24gYm90aCB0aGUgcmVzcG9uc2UgYW5kIHByZWRpY3RvcnMgdG8gYmUgYSByZWFzb25hYmxlIHNpemUKICB5MSA9IHlbMTpvcmlnXQogIERGID0gRGluZGV4WzE6b3JpZywgXQogICMgQ29weSB0aGUgZGF0YSBmcmFtZQogIERGX3dsID0gRGluZGV4CiAgIyBUZXN0IHByaW50CiAgIyBwcmludChNKQogIERGbGlzdCA8LSBsaXN0KGxvYWRpbmdzID0gTTEsIERGaW5kZXggPSBEaW5kZXgpCn0KCmBgYAoKCmBgYHtyfQojICMgVHJvdWJsZXNob290aW5nIHRoZSBkYXRhIApkZiA9IGRpZmZfaW5kZXhfZGYoYygiWExVIiwgIlhMUCIsICJYTFYiLCAiWExLIiwgIlhMWSIsICJYTEkiLCAiWExGIiwgIlhMQiIsICJYTEUiKSwgcmVzcF92YXIgPSAiU1BZIiwgc3RhcnRfZGF0ZSA9ICIyMDA0LTAxLTAxIiwgZW5kX2RhdGUgPSAiMjAwOC0xMi0zMSIsIGxhZ19wcmVkID0gMSkKcGNfZGYgPSBwY19kaWZmX2luZGV4KGRmKQojICMgcGNfZGYKIyAKIyAjIFNlZSBpZiB3ZSBjYW4gZ2V0IGFsbCB0aGUgR2xvYmFsIEVURnMgdG8gd29yawojIGRmMiA9IGRpZmZfaW5kZXhfZGYoYygiSlhJIiwgIktYSSIsICJJWEoiLCAiSVhQIiwgIklYTiIsICJSWEkiLCAiRVhJIiwgIklYRyIsICJNWEkiLCAiSVhDIiksIHJlc3BfdmFyID0gIlNQWSIsIHN0YXJ0X2RhdGUgPSAiMjAwNC0wMS0wMSIsIGVuZF9kYXRlID0gIjIwMDgtMTItMzEiLCBsYWdfcHJlZCA9IDEpCiMgaGVhZChkZjIpCiMgcGNfZGYyID0gcGNfZGlmZl9pbmRleChkZjIpCiMgCiMgIyBUZXN0IGZvciB0aGlzIGZ1bmN0aW9uCiMgdmVjXzEuMiA9IHBjYV9hdF90KHkgPSBwY19kZjJbLDFdLCB4ID0gcGNfZGYyWywtMV0sIG9yaWcgPSA3NTcsIG0gPSA0KQojIAojICMgcGNhX2F0X3QgPSBmdW5jdGlvbiAoeSwgeCwgb3JpZywgbSwgdGF1LCBhcl90ZiA9IDEsIHAgPSAxLCBwcmludF9tZGwgPSAwLCBtb2RlbCA9IDEsIGVuZCA9IE5VTEwpewojIAojICMgUnVuIHRoZSBmdW5jdGlvbgojIHZlY18xID0gcGNhX2F0X3QoeSA9IHBjX2RmWywxXSwgeCA9IHBjX2RmWywtMV0sIG9yaWcgPSA3NTcsIG0gPSA0KQojIHZlY18xJGxvYWRpbmdzCiMgCiMgIyBFeHRyYWN0IHRoZSBsb2FkaW5ncyBhbmQgYWRkCiMgdmVjXzFfciA9IHJvd1N1bXModmVjXzEkbG9hZGluZ3MpCiMgdmVjXzFfcgojIAojICMgQ2FsY3VsYXRlIGF0IGEgZGlmZmVyZW50IHBvaW50CiMgdmVjXzIgPSBwY2FfYXRfdCh5ID0gcGNfZGZbLDFdLCB4ID0gcGNfZGZbLC0xXSwgb3JpZyA9IDg1NywgbSA9IDQpCiMgCiMgIyBFeHRyYWN0IHRoZSBsb2FkaW5ncyBhbmQgYWRkCiMgdmVjXzJfciA9IHJvd1N1bXModmVjXzIkbG9hZGluZ3MpCiMgdmVjXzJfcgojIGFzLm1hdHJpeCh2ZWNfMl9yKQojIAojICMgVGhldGEgY2FsY3VsYXRpb24KIyBkb3Rwcm9kID0gYWNvcyggc3VtKHZlY18xX3IqdmVjXzJfcikgLyAoIHNxcnQoc3VtKHZlY18xX3IgKiB2ZWNfMV9yKSkgKiBzcXJ0KHN1bSh2ZWNfMl9yICogdmVjXzJfcikpICkgKQojIGRvdHByb2QKYGBgCgpgYGB7cn0KCiMnIEEgZnVuY3Rpb24gdG8gY29tcHV0ZSB0aGUgYW5nbGUgYmV0d2VlbiB0d28gdmVjdG9ycwojJwojJyBAcGFyYW0geCAtIHRoZSBmaXJzdCB2ZWN0b3IgCiMnIEBwYXJhbSB5IC0gdGhlIHNlY29uZCB2ZWN0b3IgCiMnCiMnIEByZXR1cm4gLSB0aGUgYW5nbGUgaW4gcmFkaWFucyBiZXR3ZWVuIHRoZSB2ZWN0b3JzCiMnIEBleHBvcnQKIycKIycgQGV4YW1wbGVzIC0gYW5nbGUodmVjXzFfciwgdmVjXzJfcikKYW5nbGUgPC0gZnVuY3Rpb24oeCx5KXsKICAjIENvbXB1dGUgdGhlIHByb2R1Y3Qgb2YgdGhlIHR3byB2ZWN0b3JzCiAgZG90LnByb2QgPC0geCUqJXkgCiAgIyBDb21wdXRlIHRoZSBub3JtCiAgbm9ybS54IDwtIG5vcm0oeCx0eXBlPSIyIikKICBub3JtLnkgPC0gbm9ybSh5LHR5cGU9IjIiKQogICMgQ29tcHV0ZSB0aGUgYXJjY29zCiAgdGhldGEgPC0gYWNvcyhkb3QucHJvZCAvIChub3JtLnggKiBub3JtLnkpKQogICMgUmV0dXJuIHRoZXRhIGFzIGEgbnVtZXJpYwogIHRoZXRhID0gYXMubnVtZXJpYyh0aGV0YSkKICByZXR1cm4odGhldGEpCn0KCj9hY29zCgojIGFiYyA9IGFuZ2xlKGMoMC41LDIpLCBjKDIsMC41KSkKIyBjYmEgPSBhbmdsZShjKDIsMC41KSwgYygwLjUsMikpCiMgYWJjCiMgY2JhCmBgYAoKCmBgYHtyfQojIHBjYV9hdF90ID0gZnVuY3Rpb24gKHksIHgsIG9yaWcsIG0sIHRhdSwgYXJfdGYgPSAxLCBwID0gMSwgcHJpbnRfbWRsID0gMCwgbW9kZWwgPSAxLCBlbmQgPSBOVUxMKXsKCiMnIFRoaXMgcnVucyB0aGUgUENBIGF0IHRpbWUgdCBmdW5jdGlvbgojJwojJyBAcGFyYW0gZGYgLSB0aGUgaW5wdXQgZGF0YSBmcmFtZQojJyBAcGFyYW0gbnVtX3B0cyAtIG51bWJlciBvZiBwb2ludHMgdG8gaW5jbHVkZSBpbiB0aGUgZGF0YSBmcmFtZS4gQSB2YWx1ZSBvZiA3NTAgbWVhbnMgdGhhdCB0aGVyZSBhcmUgNzUwIGRhdGEgcG9pbnRzIHRvIGNhbGN1bGF0ZSBQQ0Egb249CiMnIEBwYXJhbSBtIC0gbnVtYmVyIG9mIGluZGljZXMgdG8gdXNlCiMnIEBwYXJhbSByZWZfcHQgLSB3aGljaCB0aW1lIHBvaW50IGRvIHdlIHVzZSBhcyBhIHJlZmVyZW5jZT8KIycgQHBhcmFtIGRlZ3JlZXMgLSBkbyB3ZSBzcGVjaWZ5IHRoZSBvdXRwdXQgaW4gZGVncmVlcyBvciByYWRpYW5zPwojJwojJyBAcmV0dXJuIC0gYSB2ZWN0b3Igb2YgYW5nbGVzIGZyb20gdGhlIHJlZmVyZW5jZSBwb2ludCAKIycgQGV4cG9ydAojJwojJyBAZXhhbXBsZXMgLSBtYW55X3BjYShkZiA9IHBjX2RmLCBudW1fcHRzID0gMTIwMCwgbSA9IDUsIHJlZl9wdCA9IDEpCm1hbnlfcGNhID0gZnVuY3Rpb24oZGYsIG51bV9wdHMsIG0sIHJlZl9wdCA9IDEsIGRlZ3JlZXMgPSBUUlVFLCB1bmlfcGxvdCA9IEZBTFNFKXsKICAjIEZpbmQgdGhlIGVuZCBvZiB0aGUgZGF0YWZyYW1lCiAgbGVuX2RmID0gZGltKGRmKVsxXQogICMgQ2FsY3VsYXRlIHRoZSBudW1iZXIgb2YgaXRlcmF0aW9ucwogIG5faXRlciA9IGxlbl9kZiAtIG51bV9wdHMgKyAxCiAgIyBJbml0aWFsaXplIGEgbWF0cml4IHRvIHN0b3JlIHRoZSByZXN1bHRhbnRzLiAKICAjIFJvd3MgYXJlIGVxdWFsIHRvIHRoZSBudW1iZXIgb2YgZXhwbGFuYXRvcnkgdmFyaWFibGVzIGluIHRoZSBkYXRhIGZyYW1lCiAgIyBDb2x1bW5zIGFyZSBlcXVhbCB0byB0aGUgbnVtYmVyIG9mIGl0ZXJhdGlvbnMgd2UgYXJlIGdvaW5nIHRvIHJ1bgogIHJlc19tYXQgPSBtYXRyaXgoMCwgbnJvdyA9IChuY29sKGRmKS0xKSwgbmNvbCA9IG5faXRlcikKICAjIENhbGwgdGhlIGZ1bmN0aW9uIGFib3ZlCiAgZm9yIChpIGluIDE6bl9pdGVyKXsKICAgICMgRXh0cmFjdCB0aGUgbG9hZGluZyB2ZWN0b3JzCiAgICBsb2FkX3ZlY3MgPSBwY2FfYXRfdCh5ID0gZGZbaTooaStudW1fcHRzLTEpLDFdLCB4ID0gZGZbaTooaStudW1fcHRzLTEpLC0xXSwgb3JpZyA9IDk5OTk5OSwgbSA9IG0pJGxvYWRpbmdzCiAgICAjIENhbGN1bGF0ZSB0aGUgcmVzdWx0YW50cyBhbmQgc3RvcmUKICAgICMgcHJpbnQoYXMubWF0cml4KHJvd1N1bXMobG9hZF92ZWNzKSkpCiAgICByZXNfbWF0WyxpXSA9IGFzLm1hdHJpeChyb3dTdW1zKGxvYWRfdmVjcykpCiAgICAjIFdoeSBkb2VzIHRoaXMgY2hhbmdlIHNvIG11Y2g/CiAgfQogICMgSW5pdGlhbGl6ZSBhIHJlc3VsdGFudCBtYXRyaXgKICAjIGFuZ2xlX21hdCA9IG1hdHJpeCgwLCBucm93ID0gbl9pdGVyLCBuY29sID0gbl9pdGVyKQogIGFuZ2xlX3ZlYyA9IHJlcCgwLCBuX2l0ZXIpCiAgIyBDb21wdXRlIHRoZSBwYWlyd2lzZSBjb21wYXJpc29ucyB1c2luZyBhIGRvdWJsZSBmb3IgbG9vcCBjb2RlIGJlbG93LgogICMgZm9yIChpIGluIDE6bl9pdGVyKXsKICAjIFJlc3RyaWN0IHRvIG9uZSByb3cKICBmb3IgKGogaW4gMTpuX2l0ZXIpewogICAgIyBpZiAoaSA+PSBqKXsKICAgICAgYW5nbGVfdmVjW2pdID0gYW5nbGUocmVzX21hdFsscmVmX3B0XSwgcmVzX21hdFssal0pCiAgICAjIH0gZWxzZSB7CiAgICAgICMgcmVzX21hdFtpLGpdIDwtIAogICAgfQogICMgfQogICMgSW5wdXQgYW4gaWRlbnRpY2FsIHplcm8gZm9yIHRoZSByZWZlcmVuY2UgcG9pbnQgdG8gYXZvaWQgTmFOIHByb2JsZW1zCiAgYW5nbGVfdmVjW3JlZl9wdF0gPSAwCiAgIyBDb252ZXJ0IHRvIHJhZGlhbnMKICBpZiAoZGVncmVlcyA9PSBUUlVFKXsKICAgIGFuZ2xlX3ZlYyA9IGFuZ2xlX3ZlYyooMTgwL3BpKQogIH0gCiAgIyBQbG90IG9ubHkgaWYgdGhlcmUgaXMgdGhlIG9wdGlvbiBzcGVjaWZpZWQKICBpZiAodW5pX3Bsb3QgPT0gVFJVRSl7CiAgICAjIERlZmluZSB0aGUgc3RhcnQgYW5kIGVuZCBkYXRlCiAgICBzdGFydCA9IGluZGV4KHBjX2RmKVtudW1fcHRzXQogICAgZW5kID0gaW5kZXgocGNfZGYpW2xlbl9kZl0KICAgIHBsb3QudHMoYW5nbGVfdmVjLCB0eXBlID0gImwiLCB4bGFiID0gcGFzdGUoIk51bWJlciBvZiBUcmFkaW5nIERheXMgU2luY2UiLCBhcy5EYXRlKHN0YXJ0KSksIHlsYWIgPSAiRGVncmVlIERpZmYuIGZyb20gUmVmZXJlbmNlIFJlc3VsdGFudCIsIGx3ZCA9IDEsIG1haW4gPSBwYXN0ZSgiQW5nbGUgQmV0d2VlbiBSZXN1bHRhbnRzIGZyb20gIiwgYXMuRGF0ZShzdGFydCksICJ0byIsIGFzLkRhdGUoZW5kKSksIHN1YiA9IHBhc3RlKCJUaGlzIGlzIHJ1biBmb3IgIiwgbSwgIiBEaWZmdXNpb24gSW5kaWNlcyIpKQogIH0KICAjIHBsb3QoKQogICMgRXN0YWJsaXNoIGEgbWF4aW11bSBhbmQgbWluaW11bSB2YWx1ZQogICMgbWF4X3ZhbCA9IG1heChhbmdsZV92ZWMpCiAgIyBtaW5fdmFsID0gbWluKGFuZ2xlX3ZlYykKICAjICMgQ2FsY3VsYXRlIGluaXRhbCBhbmQgZW5kaW5nIHRpbWUgdmFsdWUKICAjIHN0YXJ0ID0gaW5kZXgoZGYpW3JlZl9wdF0KICAjIGVuZCA9IGluZGV4KGFuZ2xlX3ZlYylbbGVuZ3RoKGFuZ2xlX3ZlYyldCiAgIyBpbmRfdmFscyA9IGluZGV4KGFuZ2xlX3ZlYykgLSBzdGFydAogICMgQ3JlYXRlIGFuIGluaXRpYWwgcGxvdCBhbmQgYWRkIGxpbmVzCiAgIyA0LzIvMjAyMCAtIGZpeGluZyB0aGUgaW5kZXgKICAjIFJldHVybiB0aGUgbWF0cml4IG9mIHJlc3VsdGFudHMKICAjIHJldHVybihhbmdsZV92ZWMpCiAgbWFueV9wY2FfbGlzdCA8LSBsaXN0KGFuZ2xlcyA9IGFuZ2xlX3ZlYywgcmVzdWx0YW50cyA9IHJlc19tYXQpCn0KICAKCmBgYAoKYGBge3J9CmdoaSA9IG1hbnlfcGNhKGRmID0gcGNfZGYsIG51bV9wdHMgPSAxMjUwLCBtID0gNywgcmVmX3B0ID0gMSkKCiMgbnJvdyhwY19kZikKIyBkZWYgPSBtYW55X3BjYShkZiA9IHBjX2RmLCBudW1fcHRzID0gMTAwMCwgbSA9IDcsIHJlZl9wdCA9IDEsIHVuaV9wbG90ID0gVFJVRSkKCiMgZGVmCiMgcmVzXzEgPSBkZWYkcmVzdWx0YW50c1ssMV0KIyByZXNfMjIwID0gZGVmJHJlc3VsdGFudHNbLDIyMF0KIyAKIyBhbmcxID0gYW5nbGUocmVzXzEsIHJlc18yMjApCiMgYW5nMSooMTgwL3BpKQojIHBpCgojICMgYWNvcyhzdW0ocmVzXzEqcmVzXzIyMCkvc3FydCgoc3VtKHJlc18xXjIpKSooc3VtKHJlc18xXjIpKSkpCiMgIyBhY29zKC0wLjk5OSkqMTgwL3BpCiMgCiMgYWNvc2RlZiA9IG1hbnlfcGNhKGRmID0gcGNfZGYyLCBudW1fcHRzID0gMTAwMCwgbSA9IDcsIHJlZl9wdCA9IDEpCiMgZGltKHBjX2RmMilbMV0KIyAjIHBjX2RmMgojICMgdGVzdF9pbmQgPSBpbmRleChwY19kZilbNzUwOmRpbShwY19kZilbMV1dCiMgCiMgCiMgcGxvdC50cyhkZWYsIHR5bGUgPSAibCIpCgojIGRlZgpgYGAKCgoKYGBge3J9CiMnIFRoaXMgZnVuY3Rpb24gcnVucyBwY2EgZm9yIGFsbCBtIGluIGEgcmFuZ2UKIycKIycgQHBhcmFtIHN5bWJvbF9saXN0IC0gc3RvY2sgc3ltYm9scyB0byB1c2UKIycgQHBhcmFtIG51bV9wdHMgLSBudW1iZXIgb2YgcG9pbnRzIHRvIGluY2x1ZGUgaW4gdGhlIGRhdGEgZnJhbWUuIEEgdmFsdWUgb2YgNzUwIG1lYW5zIHRoYXQgdGhlcmUgYXJlIDc1MCBkYXRhIHBvaW50cyB0byBjYWxjdWxhdGUgUENBIG9uCiMnIEBwYXJhbSBsb3dfbSAtIGxvdyB2YWx1ZSBvZiBtLiBEZWZhdWx0cyB0byAxCiMnIEBwYXJhbSBoaWdoX20gLSBoaWdoIHZhbHVlIG9mIG0uIERlZmF1bHRzIHRvIG1heGltdW0gb2YgZXhwbGFuYXRvcnkgdmFycyBpbiBkYXRhZnJhbWUKIycgQHBhcmFtIHJlZl9wdCAtIHdoaWNoIHRpbWUgcG9pbnQgZG8gd2UgdXNlIGFzIGEgcmVmZXJlbmNlPwojJyBAcGFyYW0gZGVncmVlcyAtIGRvIHdlIHNwZWNpZnkgdGhlIG91dHB1dCBpbiBkZWdyZWVzIG9yIHJhZGlhbnM/CiMnIEBwYXJhbSByZXNwX3ZhciAtIHRoZSByZXNwb25zZSB2YXJpYWJsZSB3ZSdkIGxpa2UgdG8gZm9yZWNhc3Q7IGRlZmF1bHQgaXMgU1BZCiMnIEBwYXJhbSBjb21wbF9jYXNlIC0gZGVmYXVsdHMgdG8gdHJ1ZS4uLm9ubHkgaW5jbHVkZXMgY29tcGxldGUgY2FzZXMgaW4gdGhlIGRhdGEKIycgQHBhcmFtIGFkal9jbG9zZSAtIHVzZSBhZGp1c3RlZCBjbG9zaW5nIHByaWNlcyBmb3IgdGhlIGV4cGxhbmF0b3J5IHZhcmlhYmxlcz8gZGVmYXVsdCBpcyAxIGZvciBZRVMKIycgQHBhcmFtIHJlc3BfYWRqX2Nsb3NlIC0gdXNlIGFkanVzdGVkIGNsb3NpbmcgcHJpY2VzIGZvciB0aGUgZXhwbGFuYXRvcnkgdmFyaWFibGVzPyBkZWZhdWx0IGlzIDEgZm9yIFlFUwojJyBAcGFyYW0gc3RhcnRfZGF0ZSAtIHN0YXJ0aW5nIGRhdGEgdG8gdXNlCiMnIEBwYXJhbSBlbmRfZGF0ZSAtIGVuZGluZyBkYXRlIG9mIHRoZSBkYXRhCiMnIEBwYXJhbSBsYWdfcHJlZCAtIGRvIHdlIGxhZyB0aGUgcHJlZGljdGlvbnM/IEl0IGlzIFNUUk9OR0xZIHJlY29tbWVuZGVkIHRoYXQgdGhpcyBpcyAxCiMnCiMnIEByZXR1cm4gLSBhcCAKIycgQGV4cG9ydAojJwojJyBAZXhhbXBsZXMKbWFueV9tX3BjYSA9IGZ1bmN0aW9uKHN5bWJvbF9saXN0LCBudW1fcHRzLCBsb3dfbSA9IE5VTEwsIGhpZ2hfbSA9IE5VTEwsIHJlZl9wdCA9IDEsIGRlZ3JlZXMgPSBUUlVFLCByZXNwX3ZhciA9ICJTUFkiLCBjb21wbF9jYXNlID0gMSwgYWRqX2Nsb3NlID0gMSwgcmVzcF9hZGpfY2xvc2UgPSAxLCBzdGFydF9kYXRlID0gIjE5MDAtMDEtMDEiLCBlbmRfZGF0ZSA9IFN5cy5EYXRlKCksIGxhZ19wcmVkID0gMSwgdW5pX3Bsb3QgPSBGQUxTRSl7CiAgIyBDcmVhdGUgdGhlIGRhdGEgZnJhbWUKICBkZiA9IGRpZmZfaW5kZXhfZGYoc3ltYm9sX2xpc3QgPSBzeW1ib2xfbGlzdCwgcmVzcF92YXIgPSByZXNwX3Zhciwgc3RhcnRfZGF0ZSA9IHN0YXJ0X2RhdGUsIGVuZF9kYXRlID0gZW5kX2RhdGUsIGxhZ19wcmVkID0gbGFnX3ByZWQsIGNvbXBsX2Nhc2UgPSBjb21wbF9jYXNlLCBhZGpfY2xvc2UgPSBhZGpfY2xvc2UsIHJlc3BfYWRqX2Nsb3NlID0gcmVzcF9hZGpfY2xvc2UpCiAgIyBDb252ZXJ0IHRvIGEgcGVyY2VudCBjaGFuZ2UKICBwY19kZiA9IHBjX2RpZmZfaW5kZXgoZGYpCiAgIyBGaW5kIHRoZSBlbmQgb2YgdGhlIGRhdGFmcmFtZQogIGxlbl9kZiA9IGRpbShwY19kZilbMV0KICAjIENhbGN1bGF0ZSB0aGUgbnVtYmVyIG9mIGl0ZXJhdGlvbnMKICBuX2l0ZXIgPSBsZW5fZGYgLSBudW1fcHRzICsgMQogICMgRGVmaW5lIGhpZ2ggYW5kIGxvdyBtIGlmIG5vdCBkZWZpbmVkCiAgaWYgKGlzLm51bGwobG93X20pID09IFRSVUUpewogICAgbG93X20gPSAyCiAgfSAKICBpZiAoaXMubnVsbChoaWdoX20pID09IFRSVUUpewogICAgaGlnaF9tID0gKG5jb2wocGNfZGYpLTEpCiAgfSAKICAjIERlZmluZSB0aGUgbnVtYmVyIG9mIG0ncwogIG5vX20gPSBoaWdoX20tbG93X20gKyAxCiAgIyBJbml0aWFsaXplIGEgcGxvdHRpbmcgbWF0cml4CiAgcGxvdF9tYXRyaXggPSBtYXRyaXgoMCwgbnJvdyA9IG5faXRlciwgbmNvbCA9IG5vX20pCiAgIyBwcmludChwY19kZikKICAjIHByaW50KG1hbnlfcGNhKGRmID0gcGNfZGYsIG51bV9wdHMgPSBudW1fcHRzLCBtID0gMSwgcmVmX3B0ID0gcmVmX3B0KSkKICAjIEluaXRhbGl6ZSBhIGNvdW50IGR1bW15CiAgY291bnQgPSAxCiAgIyBMb29wIHRocm91Z2ggYW5kIGNhbGN1bGF0ZSB0aGUgYW5nbGVzCiAgZm9yIChqIGluIGxvd19tOmhpZ2hfbSl7CiAgICAjIFJ1biB0aGUgY29kZQogICAgcGxvdF9tYXRyaXhbLGNvdW50XSA9IG1hbnlfcGNhKGRmID0gcGNfZGYsIG51bV9wdHMgPSBudW1fcHRzLCBtID0gaiwgcmVmX3B0ID0gcmVmX3B0LCB1bmlfcGxvdCA9IHVuaV9wbG90KSRhbmdsZXMKICAgICMgQWRkIG9uZSB0byB0aGUgY291bnRlcgogICAgY291bnQgPSBjb3VudCArIDEKICB9CiAgIyBQbG90IHRoZSBkYXRhCiAgIyBEZWZpbmUgdGhlIHN0YXJ0IGFuZCBlbmQgZGF0ZQogIHN0YXJ0ID0gaW5kZXgocGNfZGYpW251bV9wdHNdCiAgZW5kID0gaW5kZXgocGNfZGYpW2xlbl9kZl0KICAjIGluZF92YWxzID0gaW5kZXgocGNfZGYpIC0gc3RhcnQKICAjIHByaW50KGMoc3RhcnQsIGVuZCwgaW5kX3ZhbHMpKQogICMgRmluZCBtaW4gYW5kIG1heHVtIHZhbHVlcwogIG1heF92YWwgPSBtYXgocGxvdF9tYXRyaXhbLDE6bmNvbChwbG90X21hdHJpeCldKQogIG1pbl92YWwgPSBtaW4ocGxvdF9tYXRyaXhbLDE6bmNvbChwbG90X21hdHJpeCldKQogICMgIyBDcmVhdGUgYW4gaW5pdGlhbCBwbG90IGFuZCBhZGQgbGluZXMKIGZvciAoaSBpbiAxOm5jb2wocGxvdF9tYXRyaXgpKXsKICAgIGlmIChpID09IDEpewogICAgICAjIEluaXRpYWxpemUgdGhlIHBsb3QKICAgICAgcGxvdC50cyhwbG90X21hdHJpeFssaV0sIHR5cGUgPSAibCIsIHhsYWIgPSBwYXN0ZSgiTnVtYmVyIG9mIFRyYWRpbmcgRGF5cyBTaW5jZSIsIGFzLkRhdGUoc3RhcnQpKSwgeWxhYiA9ICJEZWdyZWUgRGlmZi4gZnJvbSBSZWYuIFJlc3VsdGFudCBmb3IgU2V2ZXJhbCBNIiwgeWxpbSA9IGMobWluX3ZhbCxtYXhfdmFsKSwgbHdkID0gMSwgbHR5ID0gMiwgbWFpbiA9IHBhc3RlKCJBbmdsZSBCZXR3ZWVuIFJlc3VsdGFudHMgZnJvbSIsIGFzLkRhdGUoc3RhcnQpLCAidG8iLCBhcy5EYXRlKGVuZCkpKQogICAgfSBlbHNlIGlmKGkgJWluJSBzZXEoMiw4LDEpKSB7CiAgICAgICAgbGluZXMocGxvdF9tYXRyaXhbLGldLCBjb2wgPSBpLCBsdHkgPSAyKQogICAgfSBlbHNlIHsKICAgICAgICBsaW5lcyhwbG90X21hdHJpeFssaV0sIGNvbCA9IGksIGx0eSA9IDIpCiAgICB9CiAgfQogICMgIyBEZWZpbmUgYSBzZXF1ZW5jZSBmb3IgcGxvdHRpbmcKICBwbG90X3NlcSA9IHNlcSgxLCBuY29sKHBsb3RfbWF0cml4KSkKICAjICMgTW9kaWZ5aW5nIHRoZSBjb2RlIGJlbG93IHRvIGZpeCB0aGUgbGVnZW5kIG9uIDcuMzEuMjAyMAogIGxlZ2VuZCgidG9wbGVmdCIsIGxlZ2VuZCA9IGMoc2VxKGxvd19tLGhpZ2hfbSwxKSksIGNvbCA9IHBsb3Rfc2VxLCBsdHkgPSAyLCBsd2QgPSAyKQogICMgcGxvdC50cyhhbmdsZV92ZWMsIHR5cGUgPSAibCIsIHhsYWIgPSBwYXN0ZSgiTnVtYmVyIG9mIFRyYWRpbmcgRGF5cyBTaW5jZSIsIGFzLkRhdGUoc3RhcnQpKSwgeWxhYiA9ICJEZWdyZWUgRGlmZi4gZnJvbSBSZWZlcmVuY2UgUmVzdWx0YW50IiwgbHdkID0gMSwgbWFpbiA9IHBhc3RlKCJBbmdsZSBCZXR3ZWVuIFJlc3VsdGFudHMgZnJvbSAiLCBhcy5EYXRlKHN0YXJ0KSwgInRvIiwgYXMuRGF0ZShlbmQpKSkKICAjIFJldHVybiB0aGUgdmVjdG9yIG9mIGFuZ2xlcwogIHJldHVybihsaXN0KHBsb3RfbWF0cml4ID0gcGxvdF9tYXRyaXgsIHBjX2RmPSBwY19kZikpCn0KCgojIGRpZmZfaW5kZXhfZGYgPSBmdW5jdGlvbihzeW1ib2xfbGlzdCwgcmVzcF92YXIgPSAiU1BZIiwgY29tcGxfY2FzZSA9IDEsIGFkal9jbG9zZSA9IDEsIHJlc3BfYWRqX2Nsb3NlID0gMSwgc3RhcnRfZGF0ZSA9ICIxOTAwLTAxLTAxIiwgZW5kX2RhdGUgPSBTeXMuRGF0ZSgpLCBsYWdfcHJlZCA9IDEpewpgYGAKCmBgYHtyfQojICMgUGxvdHRpbmcgdGhlIGRhdGEKIyB1c19ldGZzID0gbWFueV9tX3BjYShjKCJYTFUiLCAiWExQIiwgIlhMViIsICJYTEsiLCAiWExZIiwgIlhMSSIpLCByZXNwX3ZhciA9ICJTUFkiLCBzdGFydF9kYXRlID0gIjIwMDQtMDEtMDEiLCBlbmRfZGF0ZSA9ICIyMDA4LTEyLTMxIiwgbGFnX3ByZWQgPSAxLCBudW1fcHRzID0gNzUwLCByZWZfcHQgPSAxKQojICMgdXNfZXRmcyA9IG1hbnlfbV9wY2EoYygiWExVIiwgIlhMUCIsICJYTFYiLCAiWExLIiwgIlhMWSIsICJYTEkiLCAiWExGIiwgIlhMQiIsICJYTEUiKSwgcmVzcF92YXIgPSAiU1BZIiwgc3RhcnRfZGF0ZSA9ICIyMDA0LTAxLTAxIiwgZW5kX2RhdGUgPSAiMjAwOC0xMi0zMSIsIGxhZ19wcmVkID0gMSwgbnVtX3B0cyA9IDc1MCwgcmVmX3B0ID0gMSkKIyBwbG90LnRzKHVzX2V0ZnNbLDFdLCB0eXBlID0gImwiKQojIGxpbmVzKHVzX2V0ZnNbLDJdLCB0eXBlID0gImwiKQojIAojIGZvciAoaSBpbiAxOm5jb2wodXNfZXRmcykpewojICAgaWYgKGkgPT0gMSl7CiMgICAgICMgSW5pdGlhbGl6ZSB0aGUgcGxvdAojICAgICBwbG90LnRzKHVzX2V0ZnNbLGldLCB0eXBlID0gImwiLCB4bGFiID0gcGFzdGUoIk51bWJlciBvZiBUcmFkaW5nIERheXMgU2luY2UiLCBhcy5EYXRlKHN0YXJ0KSksIHlsYWIgPSAiRGVncmVlIERpZmYuIGZyb20gUmVmLiBEdC4gZm9yIERpZmZlcmVudCBNIiwgbHdkID0gMSwgbWFpbiA9IHBhc3RlKCJBbmdsZSBCZXR3ZWVuIFJlc3VsdGFudHMgZnJvbSIsIGFzLkRhdGUoc3RhcnQpLCAidG8iLCBhcy5EYXRlKGVuZCkpKQojICAgfSBlbHNlIGlmKGkgJWluJSBzZXEoMiw4LDEpKSB7CiMgICAgICAgbGluZXModXNfZXRmc1ssaV0sIGNvbCA9IGksIGx0eSA9IDIpCiMgICB9IGVsc2UgewojICAgICAgIGxpbmVzKHVzX2V0ZnNbLGldLCBjb2wgPSBpLCBsdHkgPSAyKQojICAgfQojIH0KIyAjIGNvbG5hbWVzKHVzX2V0ZnMpCiMgcGxvdF9zZXEgPSBzZXEoMSwgbmNvbCh1c19ldGZzKSkKIyAjICMgTW9kaWZ5aW5nIHRoZSBjb2RlIGJlbG93IHRvIGZpeCB0aGUgbGVnZW5kIG9uIDcuMzEuMjAyMAojIGxlZ2VuZCgidG9wbGVmdCIsIGxlZ2VuZCA9IGMoc2VxKDIsNiwxKSksIGNvbCA9IHBsb3Rfc2VxLCBsdHkgPSAyLCBsd2QgPSAyKQojIAojIHN0YXJ0ID0gaW5kZXgocGNfZGYpWzEwMDBdCiMgZW5kID0gaW5kZXgocGNfZGYpWzEyNTBdCiMgaW5kX3ZhbHMgPSBpbmRleChwY19kZikgLSBzdGFydAojIGluZF92YWxzCmBgYAoKYGBge3J9CiMgYWxsX2V0ZnNfMDgKYGBgCgoKIyBVLlMuIEVURnMgUmVzdWx0cyBmb3IgMjAwNyAtIDIwMDgKCmBgYHtyfQojIENhbGwgdGhlIGFib3ZlIGZ1bmN0aW9uCnVzX2V0ZnNfMDggPSBtYW55X21fcGNhKGMoIlhMVSIsICJYTFAiLCAiWExWIiwgIlhMSyIsICJYTFkiLCAiWExJIiwgIlhMRiIsICJYTEIiLCAiWExFIiksIHJlc3BfdmFyID0gIlNQWSIsIHN0YXJ0X2RhdGUgPSAiMjAwNC0wMS0wMSIsIGVuZF9kYXRlID0gIjIwMDgtMTItMzEiLCBsYWdfcHJlZCA9IDEsIG51bV9wdHMgPSA3NTAsIHJlZl9wdCA9IDEsIGxvd19tID0gNCkKCiMgaXMubWF0cml4KHVzX2V0ZnNfMDgpCgpgYGAKCkEgbmF0dXJhbCBjcml0aWNpc20gb2YgdGhlIGFib3ZlIGZpdHMgYXJlIHRoYXQgdGhlIGRhdGEgaXMgbm9pc3kuIEEgY29tcGxpY2F0aW9uIG9mIHRoaXMgYW5hbHlzaXMgaXMgdGhlIGZhY3QgdGhhdCB0aGVyZSBpc24ndCBuZWNlc3NhcmlseSBhbnl0aGluZyB0byAicGluIiB0aGUgZGF0YSB0bywgYmVjYXVzZSB0aGUgcHJvYmxlbSBpcyB1bnN1cGVydmlzZWQuIEFzIHN1Y2gsIEkgdGhpbmsgYSBkZWNlbnQgd2F5IHRvIHBpY2tpbmcgdGhlIHdoZWF0IGZyb20gdGhlIGNoYWZmIChvciB0aGUgc2lnbmFsIGZyb20gdGhlIG5vaXNlKSBpcyB0byBhcHBseSBzb21lIHNtb290aGluZyBmaWx0ZXJzIHRvIHRoZSBhYm92ZSBkYXRhLiBUd28gb3B0aW9ucyB0byBkbyBzbyBhcmUgdGhlIG1vdmluZyBhdmVyYWdlIHNtb290aGVyIGFuZCB0aGUgTG93ZXNzIHNtb290aGVycy4gCgpgYGB7cn0KIycgQSBmdW5jdGlvbiB0byBzbW9vdGggdGhlIGRhdGEKIycKIycgQHBhcmFtIHBsb3RfbWF0X2luIC0gaW5wdXQgcGxvdCBkYXRhCiMnIEBwYXJhbSBjb2xfbnVtIC0gY29sIG5hbWUgdG8gcmVmZXJlbmNlCiMnIEBwYXJhbSBwY19kZl9pbiAtIHRoZSBpbnB1dCBwZXJjZW50YWdlIGNoYW5nZSBkYXRhc2V0CiMnIEBwYXJhbSBudW1fcHRzIC0gbnVtYmVyIG9mIHBvaW50cyB1c2VkIHRvIGNhbGN1bGF0ZSBQQ0EKIycKIycgQHJldHVybiAKIycgQGV4cG9ydAojJwojJyBAZXhhbXBsZXMgLSBwbG90X3Ntb290aChwbG90X21hdF9pbiA9IHVzX2V0ZnNfMDgkcGxvdF9tYXRyaXgsIGNvbF9udW0gPSA0LCBwY19kZl9pbiA9IHVzX2V0ZnNfMDgkcGNfZGYsIG51bV9wdHMgPSA3NTApCnBsb3Rfc21vb3RoID0gZnVuY3Rpb24ocGxvdF9tYXRfaW4sIGNvbF9udW0sIHBjX2RmX2luLCBudW1fcHRzLCBsb3dfbSl7CiAgIyBFeHRyYWN0IHRoZSByZWxldmFudCBjb2x1bW4KICBwbG90X3ZlYyA9IHBsb3RfbWF0X2luWyxjb2xfbnVtXQogICMgRmluZCB0aGUgZW5kIG9mIHRoZSBkYXRhZnJhbWUKICBsZW5fZGYgPSBkaW0ocGNfZGYpWzFdCiAgIyBSdW4gYW4gTUEgc21vb3RoZXIgb24gdGhlIGRhdGEgLSBQbHVzIG9yIG1pbnVzIDUKICB3Z3RzX3BtNSA9IGMocmVwKDEsMTEpKS8xMQogIG1hX3ZlY19wbTUgPSBzdGF0czo6ZmlsdGVyKHBsb3RfdmVjLCBzaWRlcz0yLCBmaWx0ZXI9d2d0c19wbTUpCiAgIyBQbHVzIG9yIG1pbnVzIDEwCiAgd2d0c19wbTEwID0gYyhyZXAoMSwyMSkpLzIxCiAgbWFfdmVjX3BtMTAgPSBzdGF0czo6ZmlsdGVyKHBsb3RfdmVjLCBzaWRlcz0yLCBmaWx0ZXI9d2d0c19wbTEwKQogICMgUnVuIGEgTG93ZXNzIHNtb290aGVyCiAgbG93ZXNzX3ZlYyA9IGxvd2VzcyhwbG90X3ZlYywgZiA9IDEvNikKICAjIERlZmluZSB0aGUgc3RhcnQgYW5kIGVuZCBkYXRlCiAgc3RhcnQgPSBpbmRleChwY19kZilbbnVtX3B0c10KICBlbmQgPSBpbmRleChwY19kZilbbGVuX2RmXQogICMgRmluZCB0aGUgdmFsdWUgb2YgbQogIHRydWVfbSA9IGxvd19tICsgKGNvbF9udW0gLSAxKQogICMgUGxvdCB0aGUgZGF0YQogIHBsb3QudHMocGxvdF92ZWMsIHR5cGUgPSAibCIsIHhsYWIgPSBwYXN0ZSgiTnVtYmVyIG9mIFRyYWRpbmcgRGF5cyBTaW5jZSIsIGFzLkRhdGUoc3RhcnQpKSwgeWxhYiA9IHBhc3RlMCgiRGVncmVlIERpZmYuIGZyb20gUmVmLiBSZXN1bHRhbnQgZm9yIE0gPSAiLCA3KSwgeWxpbSA9IGMoMCwxODApLCBsd2QgPSAxLCBsdHkgPSAyLCBtYWluID0gcGFzdGUoIkFuZ2xlIEJldHdlZW4gUmVzdWx0YW50cyBmcm9tIiwgYXMuRGF0ZShzdGFydCksICJ0byIsIGFzLkRhdGUoZW5kKSkpCiAgIyBBZGQgbGluZXMgdG8gdGhlIHBsb3QKICBsaW5lcyhtYV92ZWNfcG01LCBjb2wgPSAzLCBsd2QgPSAyLCBsdHkgPSAyKQogIGxpbmVzKG1hX3ZlY19wbTEwLCBjb2wgPSA0LCBsd2QgPSAyLCBsdHkgPSAyKQogIGxpbmVzKGxvd2Vzc192ZWMsIGNvbCA9IDUsIGx3ZCA9IDIsIGx0eSA9IDIpCiAgIyBBZGQgYSBsaW5lIGF0IDkwCiAgYWJsaW5lKGggPSA5MCwgY29sID0gMiwgbHdkID0gMSwgbHR5ID0gMikKICAjIEFkZCBhIGxlZ2VuZAogIGxlZ2VuZCgidG9wbGVmdCIsIGxlZ2VuZCA9IGMoIlJhdyBTZXJpZXMiLCAiTUEgKy8tIDUgRGF5cyIsICJNQSArLy0gMTAgRGF5cyIsICJMb3dlc3Mgd2l0aCBmID0gMS82IiwgIjkwIERlZ3JlZXMiKSwgY29sID0gYygxLDMsNCw1LDIpLCBsdHkgPSBjKDIsMiwyLDIsMiksIGx3ZCA9IGMoMSwyLDIsMiwxKSkKfQpgYGAKCmBgYHtyfQpwbG90X3Ntb290aChwbG90X21hdF9pbiA9IHVzX2V0ZnNfMDgkcGxvdF9tYXRyaXgsIGNvbF9udW0gPSA0LCBwY19kZl9pbiA9IHVzX2V0ZnNfMDgkcGNfZGYsIG51bV9wdHMgPSA3NTAsIGxvd19tID0gNCkKCgpgYGAKCkluIHRoZSBhYm92ZSBwbG90LCBJIGFwcGxpZWQgYSBmZXcgZmlsdGVycywgbmFtZWx5IHRoZSBtb3ZpbmcgYXZlcmFnZSBmaWx0ZXIgd2l0aCBlcXVhbCB3ZWlnaHRzIGZvciBwbHVzL21pbnVzIDUgZGF5cyBhbmQgMTAgZGF5cyBhcyB3ZWxsIGFzIHRoZSBMb3dlc3Mgd2l0aCBhIHdlaWdodCBvZiAkZiA9IDEvNiQgZm9yIGhpZ2hlciBsZXZlbHMgb2YgcHJlY2lzaW9uLiBCZWxvdyBhcmUgdGhlIHNwZWNpZmljYXRpb25zIGZvciBtb3ZpbmcgYXZlcmFnZSB3aXRoIDUgYW5kIDEwIGRheXMsIHdoZXJlICR4X3QkIGlzIHRoZSBhbmdsZSBiZXR3ZWVuIHRoZSByZXN1bHRhbnRzLgoKJCQKbV97dCw1fSA9IFxzdW1fe2ogPS01fV41IFxmcmFjezF9ezExfSB4X3t0LWp9LCBtX3t0LDEwfSA9IFxzdW1fe2ogPS0xMH1eezEwfSBcZnJhY3sxfXsyMX0geF97dC1qfQokJAoKClRoZSBMb3dlc3Mgc21vb3RoZXIgaXMgYSBzbW9vdGhlciB0aGF0IHBlciBTaHVtd2F5IGFuZCBTdG9mZmVyIFtAU2h1bXdheTIwMTZdLCBpcyBhIHRlY2huaXF1ZSAiYmFzZWQgb24gay1uZWFyZXN0IG5laWdoYm9ycyByZWdyZXNzaW9uLCB3aGVyZWluIG9uZSB1c2VzIG9ubHkgdGhlIGRhdGEgJFt4X3t0LWsvMn0sIC4uLiAsIHhfdCwgLi4uLCB4X3t0K2svMn1dJCB0byBwcmVkaWN0IHRoZSB0cnVlIHZhbHVlIG9mICR4X3QkLiBCYXNlZCBvbiBhIHZpc3VhbCBpbnNwZWN0aW9uIG9mIHRoZSBkYXRhLCBpdCBhcHBlYXJzIHRoYXQgYSBtb3JlIHByZWNpc2UgZXN0aW1hdG9yIHdhcyBpbiBvcmRlciwgc28gdGhlIExvd2VzcyBmdW5jdGlvbiBvbmx5IHVzZXMgMS82dGggb2YgdGhlIGRhdGEuCgpUaGVyZSBhcmUgc29tZSBpbnRlcmVzdGluZyB0cmVuZHMgdGhhdCBiZWFyIGRpc2N1c3Npb24uIFdoaWxlIHNvbWUgb2YgbWFjcm9lY29ub21pY3MgbWF5IGFwcGVhciB0byBiZSBsaXR0bGUgbW9yZSB0aGFuIGEgY3J5c3RhbCBiYWxsLCBvciBhIHNjaWVuY2UgYmFzZWQgdXBvbiBzdHJvbmcgcHJpb3JzLCBJIGRvbid0IGJlbGlldmUgdGhhdCB0byBiZSB0aGUgY2FzZSBoZXJlLiBJbiB0aGUgYWJvdmUgZ3JhcGgsIHRoZSBhbmdsZSBiZXR3ZWVuIHJlc3VsdGFudCB2ZWN0b3JzIGNhbGN1bGF0ZWQgZnJvbSBiYXNrZXRzIG9mIGVxdWl0eSBleGNoYW5nZS10cmFkZWQgZnVuZHMgKEVURnMpIGZvciBkaWZmZXJlbnQgc2VjdG9ycyBvZiB0aGUgVS5TLiBlY29ub215IHBvaW50LCBhbG1vc3QgYXMgYSBsZWFkaW5nIGluZGljYXRvciwgdG93YXJkcyB0aGUgb25jZS1pbi1hLWxpZmV0aW1lIHR1bXVsdCB0aGF0IHdhcyBhYm91dCB0byBncmlwIHRoZSBVLlMuIGFuZCBnbG9iYWwgZmluYW5jaWFsIG1hcmtldHMuIEluZGVlZCwgaW4gdGhlIGdyYXBoIGFib3ZlLCB0aGUgYW5nbGUgb2YgdGhlIHJlc3VsdGFudCBzZWVtcyB0byBzdGFiaWxpemUgZm9yIHRoZSBtb250aCBvZiBBdWd1c3QgMjAwOCwgd2hpY2ggY29ycmVzcG9uZHMgcm91Z2hseSB0byB0aGUgNDAwIOKAkyA0MjUgdHJhZGluZyBkYXlzIHNpbmNlIHRoZSByZWZlcmVuY2UgcG9pbnQgYXQgdGhlIGVuZCBvZiAyMDA2LiBUaGlzIGlzIGJlZm9yZSBMZWhtYW4gQnJvdGhlcnMgZGVjbGFyZWQgYmFua3J1cHRjeSwgYmVmb3JlIEFJRyB3YXMgYmFpbGVkIG91dCwgYW5kIGJlZm9yZSBDb25ncmVzcyBwYXNzZWQgVEFSUC4gSXQgcmVtYWlucyB0byBiZSBzZWVuIHdoZXRoZXIgdGhpcyBpcyBjb2luY2lkZW50YWwgb3Igd2hldGhlciB0aGVyZSByZWFsbHkgaXMgYSBsZWFkaW5nIGluZGljYXRvciBoZXJlLCBidXQgSSBiZWxpZXZlIHRoZSBxdWVzdGlvbiBpcyB3b3J0aCBhc2tpbmcgYW5kIHdvcnRoIGV4cGxvcmluZyBmdXJ0aGVyLgoKRnJvbSBhIHN0YXRpc3RpY2FsIHBlcnNwZWN0aXZlLCB0aGUgbW9zdCBpbXBvcnRhbnQgZmFjdCBhYm91dCB0aGVzZSB0cmVuZHMgaXMgdGhhdCB0aGUgYWxnb3JpdGhtIHRoYXQgcHJvZHVjZXMgdGhlbSwgbmFtZWx5IFBDQSwgaXMgKmFuIHVuc3VwZXJ2aXNlZCBsZWFybmluZyBhbGdvcml0aG0qLiBBdCBubyBwb2ludCBpbiB0aGlzIHdvcmsgaXMgdGhlcmUgYSBtb2RlbCBvZiBhbnkga2luZCB0cnlpbmcgdG8gcHJlZGljdCBneXJhdGlvbnMgaW4gdGhlIFMmUDUwMCBvciB0aGUgRG93IEpvbmVzIG9yIHRoZSByZWFsIGVjb25vbXkuIEluZGVlZCwgcmVtZW1iZXIgdGhhdCB0aGVzZSBwcmluY2lwYWwgY29tcG9uZW50cyBhcmUgYmFzZWQgdXBvbiBzZWN0b3IgRVRGcywgdGhpbmdzIGxpa2UgRW5lcmd5LCBDb25zdW1lciBTdGFwbGVzLCBhbmQgVXRpbGl0aWVzLCB3aGljaCBpbiB0dXJuIGFyZSBiYXNlZCB1cG9uIGluZGl2aWR1YWwgc3RvY2tzIC0gY29tcGFuaWVzIGxpa2UgRXh4b24sIENhcGl0YWwgT25lLCBHZW5lcmFsIEVsZWN0cmljLCBhbmQgQW1hem9uLiBUaGVzZSBzdG9jayBwcmljZXMgbWF5IHNlZW1pbmdseSBiZSBlbmlnbWF0aWMgYW5kIG5vaXN5LCBidXQgaXJvbmljYWxseSB0aGV5IGxvb2sgdGhpcyB3YXkgYmVjYXVzZSBhY2NvcmRpbmcgdG8gZWNvbm9taWMgdGhlb3J5LCB0aGV5IGFyZSBsaWtlbHkgdG8gY29udGFpbiBhbGwgdGhlIHJlbGV2YW50IGluZm9ybWF0aW9uIGFib3V0IHRoZWlyIGNvbXBhbnkgYXMgZGV0ZXJtaW5lZCBieSBtYXJrZXQgcGFydGljaXBhbnRzIFtATWFsa2llbDIwMDNdLiBXaGF0IGlmLCBpbiBhbGwgb2YgdGhlaXIgZm9yZXNpZ2h0LCB0aGV5IHNhdyB0aGUgbW9zdCBjYXRhY2x5c21pYyBlY29ub21pYyBldmVudCBvZiBvdXIgdGltZSBiZWZvcmUgaXQgaGFwcGVuZWQsIHdpdGhvdXQgZXZlbiBhaW1pbmcgdG8gZG8gc28/CgpXaGlsZSBmdXR1cmUgd29yayBpbiB0aGlzIGFyZWEgd291bGQgYmVuZWZpdCBncmVhdGx5IGZyb20gYSB2YXJpYXRpb25hbCBhdXRvZW5jb2RlciB0byBiZSBhYmxlIHRvIGZpZ3VyZSBvdXQgd2hhdCBpcyBleGFjdGx5IGEgbWVhbmluZ2Z1bCBjaGFuZ2UsIGl0IG1heSBhbHNvIGJlbmVmaXQgZnJvbSBoYXZpbmcgYWRkaXRpb25hbCBkYXRhIGZlZCBpbnRvIGl0LgoKCmBgYHtyfQojIHBsb3QKIyAjIHVzX2V0ZnNfMDhbLDRdCiMgbG93ZXNzKHVzX2V0ZnNfMDhbLDRdKQojIAojIGZvciAoaSBpbiAxOm5jb2wocGxvdF9tYXRyaXgpKXsKIyAgICAgaWYgKGkgPT0gMSl7CiMgICAgICAgIyBJbml0aWFsaXplIHRoZSBwbG90CiMgICAgICAgcGxvdC50cyhwbG90X21hdHJpeFssaV0sIHR5cGUgPSAibCIsIHhsYWIgPSBwYXN0ZSgiTnVtYmVyIG9mIFRyYWRpbmcgRGF5cyBTaW5jZSIsIGFzLkRhdGUoc3RhcnQpKSwgeWxhYiA9ICJEZWdyZWUgRGlmZi4gZnJvbSBSZWYuIFJlc3VsdGFudCBmb3IgU2V2ZXJhbCBNIiwgeWxpbSA9IGMobWluX3ZhbCxtYXhfdmFsKSwgbHdkID0gMSwgbHR5ID0gMiwgbWFpbiA9IHBhc3RlKCJBbmdsZSBCZXR3ZWVuIFJlc3VsdGFudHMgZnJvbSIsIGFzLkRhdGUoc3RhcnQpLCAidG8iLCBhcy5EYXRlKGVuZCkpKQojICAgICB9IGVsc2UgaWYoaSAlaW4lIHNlcSgyLDgsMSkpIHsKIyAgICAgICAgIGxpbmVzKHBsb3RfbWF0cml4WyxpXSwgY29sID0gaSwgbHR5ID0gMikKIyAgICAgfSBlbHNlIHsKIyAgICAgICAgIGxpbmVzKHBsb3RfbWF0cml4WyxpXSwgY29sID0gaSwgbHR5ID0gMikKIyAgICAgfQojICAgfQoKYGBgCgoKCgoKIyBBcHBlbmRpeAoKCiMjIFUuUy4gRVRGcyBSZXN1bHRzIGZvciB0aGUgMjAxMSAtIDIwMTIKCmBgYHtyfQojIENhbGwgdGhlIGFib3ZlIGZ1bmN0aW9uCnVzX2V0ZnNfMTIgPSBtYW55X21fcGNhKGMoIlhMVSIsICJYTFAiLCAiWExWIiwgIlhMSyIsICJYTFkiLCAiWExJIiwgIlhMRiIsICJYTEIiLCAiWExFIiksIHJlc3BfdmFyID0gIlNQWSIsIHN0YXJ0X2RhdGUgPSAiMjAwOC0wMS0wMSIsIGVuZF9kYXRlID0gIjIwMTItMTItMzEiLCBsYWdfcHJlZCA9IDEsIG51bV9wdHMgPSA3NTAsIHJlZl9wdCA9IDEsIGxvd19tID0gNCkKYGBgCgojIyBVLlMuIEVURnMgUmVzdWx0cyBmb3IgdGhlIDIwMTMgLSAyMDE0CgoKYGBge3J9CiMgQ2FsbCB0aGUgYWJvdmUgZnVuY3Rpb24KdXNfZXRmc18xNCA9IG1hbnlfbV9wY2EoYygiWExVIiwgIlhMUCIsICJYTFYiLCAiWExLIiwgIlhMWSIsICJYTEkiLCAiWExGIiwgIlhMQiIsICJYTEUiKSwgcmVzcF92YXIgPSAiU1BZIiwgc3RhcnRfZGF0ZSA9ICIyMDEwLTAxLTAxIiwgZW5kX2RhdGUgPSAiMjAxNC0xMi0zMSIsIGxhZ19wcmVkID0gMSwgbnVtX3B0cyA9IDc1MCwgcmVmX3B0ID0gMSwgbG93X20gPSA0KQpgYGAKCiMjIFUuUy4gRVRGcyBSZXN1bHRzIGZvciB0aGUgMjAxNSAtIDIwMTYKCgpgYGB7cn0KIyBDYWxsIHRoZSBhYm92ZSBmdW5jdGlvbgp1c19ldGZzXzE2ID0gbWFueV9tX3BjYShjKCJYTFUiLCAiWExQIiwgIlhMViIsICJYTEsiLCAiWExZIiwgIlhMSSIsICJYTEYiLCAiWExCIiwgIlhMRSIpLCByZXNwX3ZhciA9ICJTUFkiLCBzdGFydF9kYXRlID0gIjIwMTItMDEtMDEiLCBlbmRfZGF0ZSA9ICIyMDE2LTEyLTMxIiwgbGFnX3ByZWQgPSAxLCBudW1fcHRzID0gNzUwLCByZWZfcHQgPSAxLCBsb3dfbSA9IDQpCgpgYGAKCgoKCgojIyBVLlMuICsgQm9uZCBFVEYgUmVzdWx0cyBmb3IgMjAwNyAtIDIwMDgKCgoKCgpgYGB7cn0KIyBDYWxsIHRoZSBhYm92ZSBmdW5jdGlvbgphbGxfZXRmc18wOCA9IG1hbnlfbV9wY2EoYygiWExVIiwgIlhMUCIsICJYTFYiLCAiWExLIiwgIlhMWSIsICJYTEkiLCAiWExGIiwgIlhMQiIsICJYTEUiLCAiU0hZIiwgIklFRiIsICJUTFQiLCAiTFFEIiksIHJlc3BfdmFyID0gIlNQWSIsIHN0YXJ0X2RhdGUgPSAiMjAwNC0wMS0wMSIsIGVuZF9kYXRlID0gIjIwMDgtMTItMzEiLCBsYWdfcHJlZCA9IDEsIG51bV9wdHMgPSA3NTAsIHJlZl9wdCA9IDEsIGxvd19tID0gOCkKCiMgdXNfZXRmc18wOApgYGAKCiMjIFUuUy4gKyBCb25kIEVURiBSZXN1bHRzIGZvciB0aGUgMjAxMSAtIDIwMTIKCmBgYHtyfQojIENhbGwgdGhlIGFib3ZlIGZ1bmN0aW9uCmFsbF9ldGZzXzEyID0gbWFueV9tX3BjYShjKCJYTFUiLCAiWExQIiwgIlhMViIsICJYTEsiLCAiWExZIiwgIlhMSSIsICJYTEYiLCAiWExCIiwgIlhMRSIsICJTSFkiLCAiSUVGIiwgIlRMVCIsICJMUUQiKSwgcmVzcF92YXIgPSAiU1BZIiwgc3RhcnRfZGF0ZSA9ICIyMDA4LTAxLTAxIiwgZW5kX2RhdGUgPSAiMjAxMi0xMi0zMSIsIGxhZ19wcmVkID0gMSwgbnVtX3B0cyA9IDc1MCwgcmVmX3B0ID0gMSwgbG93X20gPSA4KQpgYGAKCiMjIFUuUy4gKyBCb25kIEVURiBSZXN1bHRzIGZvciB0aGUgMjAxMyAtIDIwMTQKCgpgYGB7cn0KIyBDYWxsIHRoZSBhYm92ZSBmdW5jdGlvbgphbGxfZXRmc18xNCA9IG1hbnlfbV9wY2EoYygiWExVIiwgIlhMUCIsICJYTFYiLCAiWExLIiwgIlhMWSIsICJYTEkiLCAiWExGIiwgIlhMQiIsICJYTEUiLCAiU0hZIiwgIklFRiIsICJUTFQiLCAiTFFEIiksIHJlc3BfdmFyID0gIlNQWSIsIHN0YXJ0X2RhdGUgPSAiMjAxMC0wMS0wMSIsIGVuZF9kYXRlID0gIjIwMTQtMTItMzEiLCBsYWdfcHJlZCA9IDEsIG51bV9wdHMgPSA3NTAsIHJlZl9wdCA9IDEsIGxvd19tID0gOCkKYGBgCgojIyBVLlMuICsgQm9uZCBFVEYgUmVzdWx0cyBmb3IgdGhlIDIwMTUgLSAyMDE2CgoKYGBge3J9CiMgQ2FsbCB0aGUgYWJvdmUgZnVuY3Rpb24KYWxsX2V0ZnNfMTYgPSBtYW55X21fcGNhKGMoIlhMVSIsICJYTFAiLCAiWExWIiwgIlhMSyIsICJYTFkiLCAiWExJIiwgIlhMRiIsICJYTEIiLCAiWExFIiwgIlNIWSIsICJJRUYiLCAiVExUIiwgIkxRRCIpLCByZXNwX3ZhciA9ICJTUFkiLCBzdGFydF9kYXRlID0gIjIwMTItMDEtMDEiLCBlbmRfZGF0ZSA9ICIyMDE2LTEyLTMxIiwgbGFnX3ByZWQgPSAxLCBudW1fcHRzID0gNzUwLCByZWZfcHQgPSAxLCBsb3dfbSA9IDgpCmBgYAoKCiMjIFVuaXZhcmlhdGUgQ0FWaWFSIE1vZGVsIFNwZWNpZmljYXRpb25zCgpIb3dldmVyLCB3b3JrIG5lZWRlZCB0byBiZSBkb25lIHRvIGFsaWduIHRoZSBkaWZmdXNpb24gaW5kZXggbW9kZWwgd2l0aCB0aGUgQ0FWaWFSIG1vZGVsLCB3aGljaCBpcyBkZWZpbmVkIGJlbG93LiBUaGUgZm9sbG93aW5nIHZhcmlhYmxlcyBhcmUgcmVxdWlyZWQgZm9yIHVzZSBpbiB0aGUgQ0FWaWFSIG1vZGVsLiBGb3IgZWFzZSBvZiBub3RhdGlvbiwgdGhlc2UgYXJlIHNvdXJjZWQgZGlyZWN0bHkgZnJvbSB0aGUgRW5nbGUgYW5kIE1hbmdhbmVsbGkgMjAwNCBDQVZpYVIgcGFwZXIgW0BFbmdsZTIwMDRdLCB3aXRoIHNvbWUgYWRkZWQgZGVzY3JpcHRpb246CgotICQoeV90KV97dD0xfV5UJCBpcyBhICJ2ZWN0b3Igb2YgcG9ydGZvbGlvIHJldHVybnMiCi0gJFx0aGV0YSQgaXMgdGhlICJwcm9iYWJpbGl0eSBhc3NvY2lhdGVkIHdpdGggVmFSIiAoYSA1JSBWYVIgd291bGQgbWVhbiAkXHRoZXRhID0gMC4wNSQpCi0gJFxib2xkc3ltYm9se3hfdH0kIGlzIGEgInZlY3RvciBvZiB0aW1lICR0JCBvYnNlcnZhYmxlIHZhcmlhYmxlcyIKLSAkZl90KFxib2xkc3ltYm9se1xiZXRhfSkgXGVxdWl2IGZfdChcYm9sZHN5bWJvbHt4X3t0LTF9LCBcYm9sZHN5bWJvbHtcYmV0YV9cdGhldGF9fSkkIGlzIHRoZSAidGltZSAkdCQiLCAiJFx0aGV0YSQgcXVhbnRpbGUgb2YgdGhlIGRpc3RyaWJ1dGlvbiBvZiBwb3J0Zm9saW8gcmV0dXJucyBmb3JtZWQgYXQgdGltZSAkdC0xJCIKClRoZSBhdXRob3JzIHRoZW4gZGVzY3JpYmUgYSAiZ2VuZXJpYyBDQVZpYVIgc3BlY2lmaWNhdGlvbiIgYXMgZm9sbG93czoKCiQkCmZfdChcYm9sZHN5bWJvbHtcYmV0YX0pID0gXGJldGFfMCArIFxzdW1fe2k9MX1ecSBcYmV0YV9pIGZfe3QtMX0oXGJvbGRzeW1ib2x7XGJldGF9KSArIFxzdW1fe2o9MX1eciBcYmV0YV97cStqfSBsKFxib2xkc3ltYm9se3hfe3Qtan19KQokJAoKV2hhdCBpcyBpbnRlcmVzdGluZyBhYm91dCB0aGUgZ2VuZXJhbCBzZXR1cCBpcyB0aGF0IHRoZXJlIGFyZSB0d28gbWFpbiBjb21wb25lbnRzIHRvIHRoZSBtb2RlbCAtIGxhZ2dlZCBvYnNlcnZlZCB2YXJpYWJsZXMgKHJlcHJlc2VudGVkIGJ5ICRsJCkgYW5kIGxhZ2dlZCB2YWx1ZXMgb2YgdW5rbm93biBwYXJhbWV0ZXJzLCB3aGljaCBpbiB0aGUgc3BlY2lmaWNhdGlvbiBiZWxvdyBpcyB1c2VkIGFzIG1vdmluZyBhdmVyYWdlIHRlcm1zLiBBcyBzdWNoLCBpdCBpcyByZWFzb25hYmxlIHRvIGdlbmVyYWxpemUgdGhlIHNwZWNpZmljYXRpb25zIGJlbG93IGFzIG5vbmxpbmVhciBBUk1BIG1vZGVscyB3aGVyZSAkeV97dC0xfSQgdGVybXMgcmVmZXIgdG8gcHJldmlvdXMgcmV0dXJucywgd2hlcmVhcyAkZl97dC0xfShcYmV0YV8xKSQgdGVybXMgcmVmZXIgdG8gcHJldmlvdXMgcHJlZGljdGlvbnMuCgoKIyMjIEFkYXB0aXZlIENBVmlhUiBNb2RlbAoKQ29uc2lkZXIgdGhlIGZvbGxvd2luZyBtb2RlbDoKCiQkCmZfdChcYmV0YV8xKSA9IGZfe3QtMX0oXGJldGFfMSkgKyBcYmV0YV8xXGxlZnRbXGxlZnQoMSsgXGV4cChHW3lfe3QtMX0gLSBmX3t0LTF9KFxiZXRhXzEpXSkgIFxyaWdodCleey0xfSAtIFx0aGV0YSBccmlnaHRdIAokJAoKRm9sbG93aW5nIEVuZ2xlIGFuZCBNYW5nYW5lbGxpJ3MgMjAwNCBwYXBlciwgd2UgY2hvb3NlICRHID0gMTAkLCBzbyB0aGF0IGlzIHdoYXQgaXMgdXNlZCBpbiB0aGUgcmVzdWx0cyBzZWN0aW9uIG9mIHRoaXMgcGFwZXIuIFRoZSBhdXRob3JzIHN0YXRlIHRoZSByZWFzb24gZm9yIHRoZSBzZWVtaW5nbHkgYXJiaXRyYXJ5IGNob2ljZSBpcyB0aGF0IHdoaWxlICJ0aGUgcGFyYW1ldGVyIEcgaXRzZWxmIGNvdWxkIGJlIGVzdGltYXRlZDsgaG93ZXZlciwgdGhpcyB3b3VsZCBnbyBhZ2FpbnN0IHRoZSBzcGlyaXQgb2YgdGhpcyBtb2RlbCwgd2hpY2ggaXMgc2ltcGxpY2l0eSIuIFByZXZpb3VzIHNlbnNpdGl2aXR5IGFuYWx5c2lzIHNob3dlZCB0aGF0IHJ1bm5pbmcgdGhlIGFkYXB0aXZlIG1vZGVsIHdpdGggJEcgPSA1JCBkaWQgbm90IG1hdGVyaWFsbHkgYWZmZWN0IHRoZSBWYVIgcHJlZGljdGlvbnMgLSB0aGUgYWNjdXJhY3kgd2FzIG5vdCBjaGFuZ2VkLiBXaGlsZSB0aGlzIG1vZGVsIGlzIG5vbmxpbmVhciBpbiBHIGFuZCB0b3RhbCBzY2FsZSBpbnZhcmlhbmNlIGluICRHJCB3b3VsZCBiZSBzdXJwcmlzaW5nIGdpdmVuIHRoZSBub25saW5lYXIgcmVsYXRpb25zaGlwLCB0aGUgZmFjdCB0aGF0IHRoZSBvdGhlciBmaXR0ZWQgcGFyYW1ldGVycyBsaWtlbHkgYWRqdXN0ZWQgaXMgbm90IHN1cnByaXNpbmcuCgojIyMgU3ltbWV0cmljIEFic29sdXRlIFZhbHVlIENBVmlhUiBNb2RlbAoKQmVsb3cgaXMgdGhlIHN5bW1ldHJpYyBhYnNvbHV0ZSB2YWx1ZSBDQVZpYVIgbW9kZWw6CgokJApmX3QoXGJvbGRzeW1ib2x7XGJldGF9KSA9IFxiZXRhXzEgKyBcYmV0YV8yZl97dC0xfShcYm9sZHN5bWJvbHtcYmV0YX0pICsgXGJldGFfM3x5X3t0LTF9fC4KJCQKCiMjIyBBc3ltbWV0cmljIFNsb3BlIENBVmlhUiBNb2RlbAoKQmVsb3cgaXMgdGhlIGFzeW1tZXRyaWMgc2xvcGUgQ0FWaWFSIG1vZGVsOgoKJCQKZl90KFxib2xkc3ltYm9se1xiZXRhfSkgPSBcYmV0YV8xICsgXGJldGFfMmZfe3QtMX0oXGJvbGRzeW1ib2x7XGJldGF9KSArIFxiZXRhXzMoeV97dC0xfSleKyArIFxiZXRhXzQoeV97dC0xfSleLS4KJCQKCiMjIyBJbmRpcmVjdCBHQVJDSCAoMSwxKSBDQVZpYVIgTW9kZWwKCkJlbG93IGlzIHRoZSBJbmRpcmVjdCBHQVJDSCAoMSwxKSBtb2RlbDoKCiQkCmZfdChcYm9sZHN5bWJvbHtcYmV0YX0pID0gKFxiZXRhXzEgKyBcYmV0YV8yZl97dC0xfV4yKFxib2xkc3ltYm9se1xiZXRhfSkgKyBcYmV0YV8zeV97dC0xfV4yKV57MS8yfS4KJCQKCiMjIE11bHRpdmFyaWF0ZSBDQVZpYVIgTW9kZWwgU3BlY2lmaWNhdGlvbnMKClRoZSBtdWx0aXZhcmlhdGUgQ0FWaWFSIG1vZGVsIHRha2VzIGluc3BpcmF0aW9uIGZyb20gdGhlIG1vZGVscyBkZXNjcmliZWQgYWJvdmUgaW4gc2V2ZXJhbCBzcGVjaWZpY2F0aW9ucywgYXMgbWVudGlvbmVkIGluIHRoZSBvcmlnaW5hbCBzcGVjaWZpY2F0aW9ucy4gVGhlIGdlbmVyYWwgbW9kZWwgZm9ybSBsb29rcyBsaWtlIHRoZSBzcGVjaWZpY2F0aW9uIGJlbG93OgoKJCQKZl90KFxib2xkc3ltYm9se1xiZXRhfSkgPSBcYmV0YV8wICtcc3VtX3tpPTF9XnAgXGJldGFfaSB5X3t0LWl9ICsgXHN1bV97aj0xfV5tIFxiZXRhX3tqK3B9IGZfe2osdC0xfSArIGVfdC4KJCQKCkFzIHdpdGggdGhlIHVuaXZhcmlhdGUgQ0FWaWFSIG1vZGVsLCB0aGUgb2JqZWN0IG9mIGludGVyZXN0IGlzIGEgJFx0aGV0YSQgcGVyY2VudGlsZSByZXR1cm4gYW5kIHRoZSBtb2RlbCBpcyBmaXQgaXRlcmF0aXZlbHkgdG8gbWluaW1pemUgdGhlIGxvc3MgZnVuY3Rpb24gb24gdGhlIHRyYWluaW5nIGRhdGEuIEhvd2V2ZXIsIHRoZXJlIGFyZSBzb21lIG5vdGFibGUgZGlmZmVyZW5jZXMgYmV0d2VlbiB0aGUgdW5pdmFyaWF0ZSBtb2RlbCBhbmQgdGhlIG11bHRpdmFyaWF0ZSBtb2RlbC4gRmlyc3QsIHRoZXJlIGFyZSBubyBtb3ZpbmcgYXZlcmFnZSB0ZXJtcyAobGFnZ2VkIGVycm9yIHRlcm1zKSAtIHRoZSByZWFzb25pbmcgZm9yIHRoaXMgaXMgYmVjYXVzZSB0aGlzIG1vZGVsIGFpbXMgZm9yIGEgY2xlYXIgZWNvbm9taWMgaW50ZXJwcmV0YXRpb24sIGFuZCBjcmlzcCBpbnRlcnByZXRhdGlvbnMgb2YgTUEgbW9kZWxzIGFyZSBoYXJkZXIgdG8gY3JlYXRlLiBBbHNvLCBtb3ZpbmcgYXZlcmFnZSBtb2RlbHMgcmVxdWlyZSByZWN1cnNpdmUgZXN0aW1hdGlvbiBzaW5jZSBlcnJvciB0ZXJtcyBhcmUgbm90IG9ic2VydmVkLCBhbmQgc28gZGV2ZWxvcGluZyBhIG1ldGhvZCB0byB3b3JrIHdpdGggdGhlc2UgZXJyb3JzIGluIGEgcm9idXN0IHJlZ3Jlc3Npb24gZnJhbWV3b3JrIGlzIGNoYWxsZW5naW5nLgoKU2Vjb25kLCBpbiBzb21lIG9mIHRoZSBzcGVjaWZpY2F0aW9ucyBiZWxvdywgdGhlcmUgYXJlIGxhZ2dlZCByZXR1cm4gdmFyaWFibGVzLiBUaGlzIGlzIHNpbWlsYXIgdG8gdGhlIHVuaXZhcmlhdGUgQ0FWaWFSIHNwZWNpZmljYXRpb24sIHRob3VnaCB0aGVyZSBpcyBvZnRlbiBtb3JlIHRoYW4gMSBsYWcgYXMgaW4gdGhlIHVuaXZhcmlhdGUgbW9kZWwgLSB0aGVyZSBhcmUgJHAkIGxhZ3MgaW4gdGhlIGRhdGFzZXQuIFRoaXJkLCBpbiBhbGwgb2YgdGhlIHNwZWNpZmljYXRpb25zIGJlbG93LCB0aGVyZSBhcmUgJG0kIGRpZmZ1c2lvbiBpbmRpY2VzIHVzZWQgaW4gZWFjaCBtb2RlbCBsYWdnZWQgYnkgb25lIHRpbWUgc3RlcCB0byBhdm9pZCBsb29rLWFoZWFkIGJpYXMuCgoKIyMjIE11bHRpdmFyaWF0ZSBDQVZpYVI6IE5vIExhZ3MgTW9kZWwKCiQkCmZfdChcYm9sZHN5bWJvbHtcYmV0YX0pID0gXGJldGFfMCArXHN1bV97aj0xfV5tIFxiZXRhX3tqfSBmX3tqLHQtMX0gKyBlX3QKJCQKCiMjIyBNdWx0aXZhcmlhdGUgQ0FWaWFSIHdpdGggQXV0b3JlZ3Jlc3NpdmUgVGVybXMgQWRkZWQKCiQkCmZfdChcYm9sZHN5bWJvbHtcYmV0YX0pID0gXGJldGFfMCArXHN1bV97aT0xfV5wIFxiZXRhX2kgeV97dC1pfSArIFxzdW1fe2o9MX1ebSBcYmV0YV97aitwfSBmX3tqLHQtMX0gKyBlX3QKJCQKCiMjIyBNdWx0aXZhcmlhdGUgQ0FWaWFSIHdpdGggU3ltbWV0cmljIEFic29sdXRlIFZhbHVlIEF1dG9yZWdyZXNzaXZlIFRlcm1zIEFkZGVkCgokJApmX3QoXGJvbGRzeW1ib2x7XGJldGF9KSA9IFxiZXRhXzAgK1xzdW1fe2k9MX1ecCBcYmV0YV9pIHx5X3t0LWl9fCArIFxzdW1fe2o9MX1ebSBcYmV0YV97aitwfSBmX3tqLHQtMX0gKyBlX3QKJCQKCiMjIyBNdWx0aXZhcmlhdGUgQ0FWaWFSIHdpdGggQXN5bW1ldHJpYyBTbG9wZSBBdXRvcmVncmVzc2l2ZSBUZXJtcyBBZGRlZAoKJCQKZl90KFxib2xkc3ltYm9se1xiZXRhfSkgPSBcYmV0YV8wICtcc3VtX3tpPTF9XnAgXGJldGFfaSAoeV97dC1pfSlfKyArIFxzdW1fe2o9cCsxfV57MnB9IFxiZXRhX2kgKHlfe3QtaX0pXy0gKyBcc3VtX3trPTF9Xm0gXGJldGFfe2srMnB9IGZfe2ssdC0xfSArIGVfdAokJAoKCiMjIEZpdHRpbmcgdGhlIE1vZGVscwoKVG8gZml0IHRoZSBtb2RlbHMsIGFuIG9wdGltYWwgdmFsdWUgb2YgJG0kIGRpZmZ1c2lvbiBpbmRpY2VzIGFuZCAkcCQgYXV0b3JlZ3Jlc3NpdmUgdGVybXMgYXJlIGFkZGVkIChvciAkMnAkIGluIHRoZSBjYXNlIG9mIHRoZSBhc3ltbWV0cmljIHNsb3BlIG1vZGVsKS4gVGhlIG9wdGltYWwgdmFsdWVzIG9mIHRoZXNlIHBhcmFtZXRlcnMgYXJlIGRldGVybWluZWQgdXNpbmcgYSB2YWxpZGF0aW9uIGRhdGFzZXQuIEluIGFsbCBvZiB0aGUgcnVucyBiZWxvdywgdGhlcmUgYXJlIGEgdG90YWwgb2YgNSB5ZWFycyBvZiB0cmFkaW5nIGRheXMsIG9yIGFib3V0IDEsMjYwIGRheXMgYXNzdW1pbmcgMjUyIHRyYWRpbmcgZGF5cyBhIHllYXIuIFRoZSBhZGp1c3RlZCBjbG9zaW5nIHByaWNlcyBhcmUgbG9nZ2VkIGFuZCBkaWZmZXJlbmNlZCwgc2hvcnRlbmluZyB0aGUgZGF0YXNldCBieSBvbmUuIEFmdGVyIGRvaW5nIHRoaXMsIHRoZSBsYXN0IDI1MCBkYXRhIHBvaW50cyBhcmUgcmVzZXJ2ZWQgYXMgdGVzdCBkYXRhLCBhbmQgdGhlIDI1MCBkYXRhIHBvaW50cyBiZWZvcmUgdGhhdCBhcmUgdXNlZCBhcyBhIHZhbGlkYXRpb24gc2V0LiBNZWFzdXJlZCBieSB0aGUgbG9zcyBmdW5jdGlvbiB3cml0dGVuIG91dCBiZWxvdywgdGhlIHZhbHVlcyBvZiAkcCQgYW5kICRtJCB0aGF0IG1pbmltaXplIGxvc3NlcyBhcmUgY2hvc2VuIGFuZCB0aGUgb3B0aW1hbCBtb2RlbCBpcyByZWZpdCBvdmVyIGJvdGggdGhlIHRyYWluaW5nIGFuZCB0aGUgdmFsaWRhdGlvbiBkYXRhIGNvbWJpbmVkIGFuZCB0aGVuIGV2YWx1YXRlZCBvbiB0aGUgdGVzdCBkYXRhLiBOb3RlIHRoYXQgdGhlcmUgaXMgYW4gb3B0aW1hbCBtb2RlbCB3aGljaCBpcyBjaG9zZW4gZm9yIGVhY2ggb2YgdGhlIGZvdXIgbXVsdGl2YXJpYXRlIENBVmlhUiBzcGVjaWZpY2F0aW9ucyBkZXNjcmliZWQgYWJvdmUsIHNvIHRoZXJlIGFyZSA0IG9wdGltYWwgc2V0cyBvZiAkcCQgYW5kICRtJCBjaG9zZW4gZm9yIGVhY2ggc2V0IG9mIG1vZGVscy4gVGh1cywgdGhlcmUgYXJlIDggbW9kZWxzIGNvbXBhcmVkIG9uIHRoZSB0ZXN0IGRhdGEgLSA0IHVuaXZhcmlhdGUgQ0FWaWFSIG1vZGVscyBhbmQgNCBtdWx0aXZhcmlhdGUgQ0FWaWFSIG1vZGVscy4KCkZyb20gdGhlIENBVmlhUiBwYXBlciwgdGhlICRcdGhldGEkdGggcmVncmVzc2lvbiBxdWFudGlsZSBpcyBkZWZpbmVkIGFzIGFueSAkXGJvbGRzeW1ib2x7XGhhdHtcYmV0YX19JCB0aGF0IHNvbHZlcyB0aGUgZm9sbG93aW5nIGxvc3MgZnVuY3Rpb246CgokJApcb3ZlcnNldHthcmdtaW59XGJldGEgXGZyYWN7MX17VH1cc3VtX3t0PTF9XlQgW1x0aGV0YSAtIEkoeV90IDwgZl90KFxib2xkc3ltYm9se1xiZXRhfSkpXVt5X3QgLSBmX3QoXGJvbGRzeW1ib2x7XGJldGF9KV0KJCQKCiMgQ29kZQoKVGhlIGNvZGUgY2FuIGJlIGZvdW5kIGF0IHRoZSBsb2NhdGlvbiBsaXN0ZWQgYmVsb3cgaW4gdGhlICJTVEFUXzc3MV9DbGFzc19Qcm9qZWN0LlJtZCIgZmlsZS4KCmh0dHBzOi8vZ2l0aHViLmNvbS9zdGV2ZW5tb2VuL3N0YXRfNzcxX2ZpbmFsX3Byb2plY3QKCiMgQmlnIEhNTSBGdW5jdGlvbgoKYGBge3IsIGV2YWwgPSBGQUxTRX0KIyBOb3csIHdlIG5lZWQgdG8gd3JpdGUgZXZlcnl0aGluZyBhcyBhIGJpZyBmdW5jdGlvbgoKaG1tX2JpZyA9IGZ1bmN0aW9uKGRmLCBoaXN0X3Bsb3RzID0gVFJVRSwgUF9hbHQgPSBOVUxMKXsKICAjIFN1YnNldCBvdXIgZGF0YSBmcmFtZSB1c2luZyB3aGljaCBjb2x1bW5zCiAgIyBzbWFsbF90ZXN0ID0gdGVzdF9sb3NzWyx3aGljaF9jb2xzXQogICMgU2V0IGEgdmFsdWUgb2YgVCBhbmQgSwogIFQgPSBucm93KGRmKQogIEsgPSBuY29sKHYpCiAgIyBBc3NpZ24gYSB2YWx1ZSBvZiBQCiAgaWYgKGlzLm51bGwoUF9hbHQpPT0gVFJVRSl7CiAgICAjIEFzc2lnbiBhIDkwJSBjaGFuY2Ugb2Ygc3RheWluZyBwdXQKICAgIFAgPSBjYmluZChjKDAuOSwwLjEpLGMoMC4xLDAuOSkpCiAgfSBlbHNlewogICAgIyBTdGF5IHdoZXJlIHlvdSBhcmUKICAgIFAgPSBQX2FsdAogIH0KICAjIFRyYW5zZm9ybSB0aGUgZGF0YXNldAogICMgbG9nX3Rlc3QgPSBsb2coc21hbGxfdGVzdCkKICAjIFBsb3QgdGhlIGRhdGEKICAjIGlmIChoaXN0X3Bsb3RzID09IFRSVUUpewogICMgICAjIFBsb3QgdGhlc2UgZGF0YQogICMgICBwYXIobWZyb3c9IGMoMiwyKSkKICAjICAgIyBUcmFuc2Zvcm0gdGhlIGRhdGFzZXQKICAjICAgbG9nX3Rlc3QgPSBsb2coc21hbGxfdGVzdCkKICAjICAgIyBGaXJzdCwgdGhlIHVuLXRyYW5zZm9ybWVkIGhpc3RvZ3JhbXMKICAjICAgaGlzdChzbWFsbF90ZXN0WywxXSwgYnJlYWtzID0gMjUpCiAgIyAgIGhpc3Qoc21hbGxfdGVzdFssMl0sIGJyZWFrcyA9IDI1KQogICMgICAjIFBsb3QgdGhlIGRhdGEgd2l0aCBhbiBvdmVyc2V0IGhpc3RvZ3JhbQogICMgICBoPSBoaXN0KGxvZ190ZXN0WywxXSwgYnJlYWtzID0gMjUpCiAgIyAgICMgT3ZlcnNldCBhIGRlbnNpdHkgZnVuY3Rpb24KICAjICAgeGZpdDwtc2VxKG1pbihsb2dfdGVzdFssMV0pLG1heChsb2dfdGVzdFssMV0pLGxlbmd0aD00MCkKICAjICAgeWZpdDwtZG5vcm0oeGZpdCxtZWFuPW1lYW4obG9nX3Rlc3RbLDFdKSxzZD1zZChsb2dfdGVzdFssMV0pKQogICMgICB5Zml0IDwtIHlmaXQqZGlmZihoJG1pZHNbMToyXSkqbGVuZ3RoKGxvZ190ZXN0WywxXSkKICAjICAgbGluZXMoeGZpdCwgeWZpdCwgY29sPSJibHVlIiwgbHdkPTIpCiAgIyAgICMgUmVwZWF0IHRoZSBzYW1lIHRoaW5nCiAgIyAgIGg9IGhpc3QobG9nX3Rlc3RbLDJdLCBicmVha3MgPSAyNSkKICAjICAgIyBPdmVyc2V0IGEgZGVuc2l0eSBmdW5jdGlvbgogICMgICB4Zml0PC1zZXEobWluKGxvZ190ZXN0WywyXSksbWF4KGxvZ190ZXN0WywyXSksbGVuZ3RoPTQwKQogICMgICB5Zml0PC1kbm9ybSh4Zml0LG1lYW49bWVhbihsb2dfdGVzdFssMl0pLHNkPXNkKGxvZ190ZXN0WywyXSkpCiAgIyAgIHlmaXQgPC0geWZpdCpkaWZmKGgkbWlkc1sxOjJdKSpsZW5ndGgobG9nX3Rlc3RbLDJdKQogICMgICBsaW5lcyh4Zml0LCB5Zml0MiwgY29sPSJibHVlIiwgbHdkPTIpCiAgIyB9CiAgIyBGaW5kIHRoZSBtZWFucyBhbmQgU0RzCiAgIyB2MSA9IHJiaW5kKG1lYW4obG9nX3Rlc3RbLDFdKSwgc2QobG9nX3Rlc3RbLDFdKSkKICAjIEZpbmQgdGhlIG1lYW5zIGFuZCBTRHMKICAjIHYyID0gcmJpbmQobWVhbihsb2dfdGVzdFssMl0pLCBzZChsb2dfdGVzdFssMl0pKQogICMgU3RvcmUgYXMgYSBkYXRhIGZyYW1lCiAgIyBzdW1fZGYgPSBhcy5kYXRhLmZyYW1lKGNiaW5kKHYxLHYyKSkKICAjIHJvd25hbWVzKHN1bV9kZikgPC0gYygiTWVhbiIsICJTRCIpCiAgIyBjb2xuYW1lcyhzdW1fZGYpIDwtIGMoIk5vIEFSIiwgIlNBViIpCiAgIyBGb3JtYXQgbmljZWx5CiAgIyBwcmludChzdW1fZGYgJT4lIGthYmxlKGNhcHRpb24gPSAiU3VtbWFyeSBTdGF0aXN0aWNzIGZvciB0aGUgTG9nIG9mIExvc3NlcyBmcm9tIEVhY2ggTW9kZWwiLCBkaWdpdHMgPSAyKSAlPiUga2FibGVfc3R5bGluZygic3RyaXBlZCIsIGZ1bGxfd2lkdGggPSBGKSAlPiUga2FibGVfc3R5bGluZygpKQogICMgTm93IHJ1biB0aGUgSE1NCiAgIyB0aGlzIGlzIHRoZSBmdW5jdGlvbiBQcihYX3QgfCBaX3Q9aykgZm9yIG91ciBleGFtcGxlCiAgIyBXZSBuZWVkIHRvIG1vZGlmeSB0aGlzCiAgICAjIFRoaXMgaXMgdGhlIGVtaXNzaW9uIHByb2JhYmlsaXR5IGluIHRoZSAicmF0aW9uYWwgd29ybGQiLCBtb2RpZmllZCBmb3Igd2hldGhlciB3ZSBtaXNzIHBvc2l0aXZlIG9yIG5lZ2F0aXZlCiAgZW1pdF9ub3JtID0gZnVuY3Rpb24ob2JzLG1lYW4sIHNkKXsgCiAgICBkbm9ybShvYnMsIG1lYW4gPSBtZWFuLCBzZCA9IHNkKQogIH0KICAjICMgSGVyZSBpcyB3aGVyZSB3ZSB3aWxsIGlucHV0IG91ciBlbWlzc2lvbiBwcm9iYWJpbGl0aWVzIGZvciBhIEdFVgogICMgZW1pdF9nZXYgPSBmdW5jdGlvbihvYnMsbG9jLCBzY2FsZSwgc2hhcGUpewogICMgICBkZ2V2KG9icywgbG9jID0gbG9jLCBzY2FsZSA9IHNjYWxlLCBzaGFwZSA9IHNoYXBlKQogICMgfQogICMgCiAgIyAjIFRoZSBHRVYgZG9lc24ndCBoYXZlIHN1cHBvcnQgb3ZlciBhbGwgb2YgdGhlIHJlYWwgbGluZSwgd2hpY2ggaXMgYSBwcm9ibGVtCiAgIyBlbWl0X3NuID0gZnVuY3Rpb24ob2JzLGxvYywgc2NhbGUsIHNoYXBlKXsgCiAgIyAgIGRzbm9ybShvYnMsIG1lYW4gPSBsb2MsIHNkID0gc2NhbGUsIHhpID0gc2hhcGUpCiAgIyB9CiAgIyBMZXQncyB0cnkgdGhlIEd1bWJlbCBkaXN0cmlidXRpb24KICBlbWl0X2d1bWIgPSBmdW5jdGlvbihvYnMsbG9jLCBzY2FsZSl7IAogICAgZGd1bWJlbChvYnMsIGxvYyA9IGxvYywgc2NhbGUgPSBzY2FsZSkKICB9CiAgIyBPdXIgcHJpb3IgaXMgdGhhdCBib3RoIHN0YXRlcyBhcmUgZXF1YWxseSBsaWtlbHkuCiAgcHJpb3IgPSBjKDAuNSwwLjUpICNBc3N1bWVkIHByaW9yIGRpc3RyaWJ1dGlvbiBvbiBaXzEKICAjIFRoZSBtYXRyaXggd2hlcmUgd2Ugc3RvcmUgdGhlIGZvcndhcmRzIHByb2JhYmlsaXRpZXMKICBhbHBoYSA9IG1hdHJpeChucm93ID0gVCxuY29sPUspCiAgIyBJbml0aWFsaXplIGFscGhhWzEsXQogIGZvcihrIGluIDE6Syl7CiAgICBpZiAoayA9PSAxKXsKICAgICAgIyBUaGlzIGlzIHRoZSBlbWlzc2lvbiBwcm9iYWJpbGl0eSBhc3N1bWluZyBub3JtYWxpdHkKICAgICAgYWxwaGFbMSxrXSA9IHByaW9yW2tdICogZW1pdF9ub3JtKG9icyA9IGRmJFNQWVsxXSwgbWVhbiA9IG5vcm1fcGFyYW1fZGYkTWVhbiwgc2QgPSBub3JtX3BhcmFtX2RmJGBTdGFuZGFyZCBEZXZpYXRpb25gKQogICAgfSBlbHNlIGlmIChrID09IDIpewogICAgICAjIFRoaXMgaXMgdGhlIGVtaXNzaW9uIHByb2JhYmlsaXR5IGFzc3VtaW5nIEdFVgogICAgICAjIGFscGhhWzEsa10gPSBwcmlvcltrXSAqIGVtaXRfZ2V2KG9icyA9IHNtYWxsX2RmJFNQWVsxXSwgbG9jID0gZ2V2X3BhcmFtX2RmJExvY2F0aW9uLCBzY2FsZSA9IGdldl9wYXJhbV9kZiRTY2FsZSwgc2hhcGUgPSBnZXZfcGFyYW1fZGYkU2hhcGUpCiAgICAgICMgVGhpcyBpcyB0aGUgZW1pc3Npb24gcHJvYmFiaWxpdHkgYXNzdW1pbmcgU04KICAgICAgIyBhbHBoYVsxLGtdID0gcHJpb3Jba10gKiBlbWl0X3NuKG9icyA9IHNtYWxsX2RmJFNQWVsxXSwgbG9jID0gc25fcGFyYW1fZGYkTG9jYXRpb24sIHNjYWxlID0gc25fcGFyYW1fZGYkU2NhbGUsIHNoYXBlID0gc25fcGFyYW1fZGYkU2hhcGUpCiAgICAgICMgVGhpcmQgdGltZSBpcyB0aGUgY2hhcm0uLi5hc3N1bWUgYSBHdW1iZWwKICAgICAgYWxwaGFbMSxrXSA9IHByaW9yW2tdICogZW1pdF9ndW1iKG9icyA9IGRmJFNQWVsxXSwgbG9jID0gZ3VtX3BhcmFtX2RmJExvY2F0aW9uLCBzY2FsZSA9IGd1bV9wYXJhbV9kZiRTY2FsZSkKICAgIH0gZWxzZSB7CiAgICAgIHByaW50KCJrIHNob3VsZCBub3QgYmUgZ3JlYXRlciB0aGFuIDIiKQogICAgfQogIH0KICAjIEZvcndhcmQgYWxnb3JpdGhtCiAgZm9yKHQgaW4gMTooVC0xKSl7CiAgICAjIEZpbmQgdGhlIHZhbHVlIG9mIG0gYXQgZWFjaCBzdGVwCiAgICBtID0gYWxwaGFbdCxdICUqJSBQCiAgICAjIExvb3AgdGhyb3VnaCB0byB1cGRhdGUgbGV2ZWxzIG9mIGFscGhhCiAgICBmb3IoayBpbiAxOkspewogICAgICAjIGFscGhhW3QrMSxrXSA9IG1ba10qZW1pdChrLFhbdF0pIHdoYXQgSSBoYWQKICAgICAgIyBhbHBoYVt0KzEsa10gPSBtW2tdKmVtaXQoayxYW3QrMV0pIG9ubGluZQogICAgICBpZiAoayA9PSAxKXsKICAgICAgICAjIGFscGhhW3QrMSxrXSA9IG1ba10qZW1pdChrLFhbdCsxXSkgb25saW5lCiAgICAgICAgYWxwaGFbdCsxLGtdID0gbVtrXSplbWl0X25vcm0ob2JzID0gZGYkU1BZW3QrMV0sIG1lYW4gPSBub3JtX3BhcmFtX2RmJE1lYW4sIHNkID0gbm9ybV9wYXJhbV9kZiRgU3RhbmRhcmQgRGV2aWF0aW9uYCkKICAgICAgfSBlbHNlIGlmIChrID09IDIpewogICAgICAgICMgQXNzdW1pbmcgYSBHRVYKICAgICAgICAjIGFscGhhW3QrMSxrXSA9IG1ba10qZW1pdF9nZXYob2JzID0gc21hbGxfZGYkU1BZW3QrMV0sIGxvYyA9IGdldl9wYXJhbV9kZiRMb2NhdGlvbiwgc2NhbGUgPSBnZXZfcGFyYW1fZGYkU2NhbGUsIHNoYXBlID0gZ2V2X3BhcmFtX2RmJFNoYXBlKQogICAgICAgICMgQXNzdW1pbmcgYSBza2V3LW5vcm1hbAogICAgICAgICMgYWxwaGFbdCsxLGtdID0gbVtrXSplbWl0X3NuKG9icyA9IHNtYWxsX2RmJFNQWVt0KzFdLCBsb2MgPSBzbl9wYXJhbV9kZiRMb2NhdGlvbiwgc2NhbGUgPSBzbl9wYXJhbV9kZiRTY2FsZSwgc2hhcGUgPSBzbl9wYXJhbV9kZiRTaGFwZSkKICAgICAgICAjIEFzc3VtaW5nIGEgR3VtYmVsCiAgICAgICAgYWxwaGFbdCsxLGtdID0gbVtrXSplbWl0X2d1bWIob2JzID0gZGYkU1BZW3QrMV0sIGxvYyA9IGd1bV9wYXJhbV9kZiRMb2NhdGlvbiwgc2NhbGUgPSBndW1fcGFyYW1fZGYkU2NhbGUpCiAgICAgIH0gZWxzZSB7CiAgICAgICAgcHJpbnQoImsgc2hvdWxkIG5vdCBiZSBncmVhdGVyIHRoYW4gMiIpCiAgICAgIH0KICAgICAgIyBhbHBoYVt0KzEsa10gPSBtW2tdKmVtaXQob2JzID0gbG9nX3Rlc3RbdCsxLGtdLCBtZWFuID0gc3VtX2RmWzEsa10sIHNkID0gc3VtX2RmWzIsa10pCiAgICB9CiAgfQogICMgSW5pdGFsaXplIGEgYmV0YSBtYXRyaXgKICBiZXRhID0gbWF0cml4KG5yb3cgPSBULG5jb2w9SykKICAjIEluaXRpYWxpemUgYmV0YQogIGZvcihrIGluIDE6Syl7CiAgICBiZXRhW1Qsa10gPSAxCiAgfQogICMgQmFja3dhcmRzIGFsZ29yaXRobQogIGZvcih0IGluIChULTEpOjEpewogICAgZm9yKGsgaW4gMTpLKXsKICAgICAgIyBNb2RpZnkgdGhlIHZhbHVlIG9mIGJldGEKICAgICAgIyBiZXRhW3Qsa10gPSBzdW0oYmV0YVt0KzEsXSpQW2ssXSplbWl0KDE6SyxYW3QrMV0pKQogICAgICBiZXRhW3Qsa10gPSBzdW0oYmV0YVt0KzEsXSpQW2ssXSplbWl0KG9icyA9IGxvZ190ZXN0W3QrMSxrXSwgbWVhbiA9IHN1bV9kZlsxLGtdLCBzZCA9IHN1bV9kZlsyLGtdKSkKICAgIH0KICB9CgogIAp9CgpgYGAKCiMgTGl0ZXJhdHVyZSBDaXRlZA==